using dynamic method calling with attr_writer methods

Discussion in 'Ruby' started by Markus Hohenhaus, May 9, 2007.

  1. I'm a total Ruby newbie looking for help.

    I'm writing an application where I need to dynamical assign object
    variables via attr_writer object methods.

    My code is something like this:

    class Test < ParentClass
    attr_reader :eek:ne, :two, :three
    attr_writer :eek:ne, :two, :three

    def initialize
    super
    end

    end
    ( I know I could use attr_accessor but for testing I'll stick to
    attr_writer and _reader)

    Now I try to call the 'Test' methods dynamical witch 'object.send' from
    within my main application:

    [...]

    @methods = ['one', 'two', 'three']

    test = Test.new

    @methods.each { |a| test.send(a, 'foo') }

    [...]

    This throws the error: ArgumentError: wrong number of Arguments (1 for
    0)

    As far as I understand, this is the correct behaviour. Because without
    the second argument, the method call returns the value of the class
    variable. So I believe, that this should work if i'll write all the
    setter and getter methods myself (which I don't want to, because I'm
    using a lot of variables).
    Are there any other methods I can use to dynamically call attr_writer
    methods to assign values to the class variables or did I get something
    wrong and made a mistake?

    --
    Posted via http://www.ruby-forum.com/.
    Markus Hohenhaus, May 9, 2007
    #1
    1. Advertising

  2. Markus Hohenhaus

    Gary Wright Guest

    On May 9, 2007, at 3:23 PM, Markus Hohenhaus wrote:

    > I'm a total Ruby newbie looking for help.
    > [...]
    > @methods.each { |a| test.send(a, 'foo') }


    > This throws the error: ArgumentError: wrong number of Arguments (1 for
    > 0)


    The problem is you are calling the 'getters' with an argument ('foo').
    Getters don't take an argument, thus the error message. You want:

    @methods.each { |a| puts test.send(a) }

    I added the puts, otherwise you won't get any output.

    If you want to call the setters, you need to send a different method
    name:

    @methods.each { |a| test.send("#{a}=", 'foo') }

    And of course you need to send an argument also.

    Gary Wright
    Gary Wright, May 9, 2007
    #2
    1. Advertising


  3. > The problem is you are calling the 'getters' with an argument ('foo').
    > Getters don't take an argument, thus the error message. You want:
    >
    > @methods.each { |a| puts test.send(a) }
    >
    > I added the puts, otherwise you won't get any output.


    Yep, this works perfectly. I already tested this.

    >
    > If you want to call the setters, you need to send a different method
    > name:
    >
    > @methods.each { |a| test.send("#{a}=", 'foo') }
    >
    > And of course you need to send an argument also.


    That's it!! Thanks. Now everything works as expected. Allthough I like
    mine better, seems more
    logical to me ;).


    --
    Posted via http://www.ruby-forum.com/.
    Markus Hohenhaus, May 9, 2007
    #3
  4. Markus Hohenhaus

    Phrogz Guest

    On May 9, 2:10 pm, Markus Hohenhaus <> wrote:
    > That's it!! Thanks. Now everything works as expected. Allthough I like
    > mine better, seems more
    > logical to me ;).


    Well, you can do that too, if you like:

    class Module
    def attr_readwrite( *methods )
    class_eval{
    methods.each{ |method_name|
    define_method( method_name ){ |*val|
    val = val.first
    unless val.nil?
    instance_variable_set( "@#{method_name}", val )
    else
    instance_variable_get( "@#{method_name}" )
    end
    }
    }
    }
    end
    end

    class Foo
    attr_readwrite :foo, :bar
    end

    f = Foo.new

    f.foo( 42 )
    p f.foo
    #=> 42
    f.foo( 12 )
    p f.foo
    #=> 12


    (I think there's a more elegant way to define the method and detect if
    it received a value, but I was too lazy to figure it out.)

    I'm pretty sure Ara T. Howard's 'attributes' gem also gives you the
    ability to do what you want, where calling the method without a
    parameter acts as a getter, and calling it with a parameter acts as a
    setter. And I bet his way is clean. :)
    Phrogz, May 9, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert William Vesterman

    Forcing attr_writer to a type?

    Robert William Vesterman, Aug 27, 2005, in forum: Ruby
    Replies:
    4
    Views:
    141
    Malte Milatz
    Aug 28, 2005
  2. Ryan Hinton

    attr_writer variation

    Ryan Hinton, Jan 26, 2006, in forum: Ruby
    Replies:
    5
    Views:
    233
    Ryan Hinton
    Jan 27, 2006
  3. Joe

    Using attr_writer?

    Joe, Feb 26, 2006, in forum: Ruby
    Replies:
    5
    Views:
    107
  4. Joe Ruby MUDCRAP-CE

    attr_reader + attr_writer?

    Joe Ruby MUDCRAP-CE, Oct 13, 2006, in forum: Ruby
    Replies:
    6
    Views:
    97
    Trans
    Oct 13, 2006
  5. aidy

    attr_writer and hash

    aidy, Jul 14, 2007, in forum: Ruby
    Replies:
    2
    Views:
    85
    Sharon Phillips
    Jul 14, 2007
Loading...

Share This Page