Setting attribute via send in Ruby 1.8.6

Discussion in 'Ruby' started by Charles Calvert, Oct 23, 2009.

  1. Using Ruby 1.8.6.

    I've run into an instance in which I'd like to set attributes of an
    instance using the send method. I've looked around, but found
    nothing, most likely because I'm using the wrong search terms.

    Example:

    class A
    attr_reader :foo
    attr_writer :foo
    end

    a = A.new
    a.send("foo", "newval")


    I get the following error: "wrong number of arguments (1 for 0)
    (ArgumentError)"

    Am I correct in thinking that this is possible, and that I'm just
    going about it the wrong way?
    --
    Charles Calvert | Web-site Design/Development
    Celtic Wolf, Inc. | Software Design/Development
    http://www.celticwolf.com/ | Data Conversion
    (703) 580-0210 | Project Management
     
    Charles Calvert, Oct 23, 2009
    #1
    1. Advertising

  2. On 10/23/2009 05:10 PM, Charles Calvert wrote:
    > Using Ruby 1.8.6.
    >
    > I've run into an instance in which I'd like to set attributes of an
    > instance using the send method. I've looked around, but found
    > nothing, most likely because I'm using the wrong search terms.
    >
    > Example:
    >
    > class A
    > attr_reader :foo
    > attr_writer :foo
    > end
    >
    > a = A.new
    > a.send("foo", "newval")
    >
    >
    > I get the following error: "wrong number of arguments (1 for 0)
    > (ArgumentError)"
    >
    > Am I correct in thinking that this is possible, and that I'm just
    > going about it the wrong way?


    Yes.

    ....












    :)

    You need to use the _setter_ method with #send - which happens to be
    called "foo=" in your case.

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Oct 23, 2009
    #2
    1. Advertising

  3. On Friday 23 October 2009, Charles Calvert wrote:
    > |Using Ruby 1.8.6.
    > |
    > |I've run into an instance in which I'd like to set attributes of an
    > |instance using the send method. I've looked around, but found
    > |nothing, most likely because I'm using the wrong search terms.
    > |
    > |Example:
    > |
    > |class A
    > | attr_reader :foo
    > | attr_writer :foo
    > |end
    > |
    > |a = A.new
    > |a.send("foo", "newval")
    > |
    > |
    > |I get the following error: "wrong number of arguments (1 for 0)
    > |(ArgumentError)"
    > |
    > |Am I correct in thinking that this is possible, and that I'm just
    > |going about it the wrong way?
    > |


    The method attr_writer generates has an equal sign appended to the name you
    give. This means that

    attr_writer :foo

    generates a method called foo=. So, if you want to call it using send, you
    need to write:

    a.send("foo=", "newval")

    I hope this helps

    Stefano
     
    Stefano Crocco, Oct 23, 2009
    #3
  4. On Fri, 23 Oct 2009 17:18:22 +0200, Robert Klemme
    <> wrote in
    <>:

    >On 10/23/2009 05:10 PM, Charles Calvert wrote:
    >> Using Ruby 1.8.6.
    >>
    >> I've run into an instance in which I'd like to set attributes of an
    >> instance using the send method. I've looked around, but found
    >> nothing, most likely because I'm using the wrong search terms.


    [snip example]

    >> I get the following error: "wrong number of arguments (1 for 0)
    >> (ArgumentError)"
    >>
    >> Am I correct in thinking that this is possible, and that I'm just
    >> going about it the wrong way?

    >
    >Yes.
    >
    >...


    The suspense almost killed me!

    >:)
    >
    >You need to use the _setter_ method with #send - which happens to be
    >called "foo=" in your case.


    Ah, now the lightbulb goes off. I should have remembered the
    convention of having the setter have an equals sign as part of the
    name. I'm too used to languages that determine which accessor is used
    based on which side of the assignment it appears rather than actually
    using a method name to syntactically simulate assignment.

    Thanks for the help.
    --
    Charles Calvert | Web-site Design/Development
    Celtic Wolf, Inc. | Software Design/Development
    http://www.celticwolf.com/ | Data Conversion
    (703) 580-0210 | Project Management
     
    Charles Calvert, Oct 23, 2009
    #4
  5. On Fri, Oct 23, 2009 at 6:40 PM, Charles Calvert <> wrote:
    > On Fri, 23 Oct 2009 17:18:22 +0200, Robert Klemme
    > <> wrote in
    > <>:
    >
    >>On 10/23/2009 05:10 PM, Charles Calvert wrote:
    >>> Using Ruby 1.8.6.
    >>>
    >>> I've run into an instance in which I'd like to set attributes of an
    >>> instance using the send method. =A0I've looked around, but found
    >>> nothing, most likely because I'm using the wrong search terms.

    >
    > [snip example]
    >
    >>> I get the following error: "wrong number of arguments (1 for 0)
    >>> (ArgumentError)"
    >>>
    >>> Am I correct in thinking that this is possible, and that I'm just
    >>> going about it the wrong way?

    >>
    >>Yes.
    >>
    >>...

    >
    > The suspense almost killed me!
    >
    >>:)
    >>
    >>You need to use the _setter_ method with #send - which happens to be
    >>called "foo=3D" in your case.

    >
    > Ah, now the lightbulb goes off. =A0I should have remembered the
    > convention of having the setter have an equals sign as part of the
    > name. =A0I'm too used to languages that determine which accessor is used
    > based on which side of the assignment it appears rather than actually
    > using a method name to syntactically simulate assignment.


    You can achieve what you want if instead of using attr_writer you roll your=
    own.
    I remember a discussion in this list regarding something like:

    class A
    def a *args
    return @a if args.empty?
    @a =3D args[0]
    end
    end

    a =3D A.new
    a.a #=3D> nil
    a.a 4 #=3D> 4
    a.a #=3D> 4

    With this you can do a.send:)a, 4)

    Jesus.
     
    Jesús Gabriel y Galán, Oct 24, 2009
    #5
  6. Hello,

    > Example:
    >
    > class A
    > attr_reader :foo
    > attr_writer :foo
    > end


    You can accomplish this is one line with attr_accessor :foo .
    I think every poster has said this, but attr_reader defines:

    class A

    def foo
    @foo
    end

    end

    While attr_writer defines:

    class A

    def foo= value
    @foo = value
    end

    end

    Hope this helps,
    Rob
    --
    Posted via http://www.ruby-forum.com/.
     
    Robert Gleeson, Oct 24, 2009
    #6
  7. On 10/24/2009 09:06 AM, Jesús Gabriel y Galán wrote:
    > On Fri, Oct 23, 2009 at 6:40 PM, Charles Calvert <> wrote:
    >> On Fri, 23 Oct 2009 17:18:22 +0200, Robert Klemme
    >> <> wrote in
    >> <>:
    >>
    >>> On 10/23/2009 05:10 PM, Charles Calvert wrote:
    >>>> Using Ruby 1.8.6.
    >>>>
    >>>> I've run into an instance in which I'd like to set attributes of an
    >>>> instance using the send method. I've looked around, but found
    >>>> nothing, most likely because I'm using the wrong search terms.

    >> [snip example]
    >>
    >>>> I get the following error: "wrong number of arguments (1 for 0)
    >>>> (ArgumentError)"
    >>>>
    >>>> Am I correct in thinking that this is possible, and that I'm just
    >>>> going about it the wrong way?
    >>> Yes.
    >>>
    >>> ...

    >> The suspense almost killed me!


    I'm glad I did not extend the pause even more. :)

    >>> :)
    >>>
    >>> You need to use the _setter_ method with #send - which happens to be
    >>> called "foo=" in your case.

    >> Ah, now the lightbulb goes off. I should have remembered the
    >> convention of having the setter have an equals sign as part of the
    >> name. I'm too used to languages that determine which accessor is used
    >> based on which side of the assignment it appears rather than actually
    >> using a method name to syntactically simulate assignment.

    >
    > You can achieve what you want if instead of using attr_writer you roll your own.
    > I remember a discussion in this list regarding something like:
    >
    > class A
    > def a *args
    > return @a if args.empty?
    > @a = args[0]
    > end
    > end
    >
    > a = A.new
    > a.a #=> nil
    > a.a 4 #=> 4
    > a.a #=> 4
    >
    > With this you can do a.send:)a, 4)


    This also has the added advantage to be easier with #instance_eval, i.e.
    you can then do

    obj = A.new
    obj.instance_eval do
    a 10
    end

    If you had to use a= in the block you would have to write "self.a = 10"
    in order to prevent recognition of "a" as a local variable.

    Nevertheless, the general convention is to use a=. Btw, you could even
    create a custom attr_accessor method that will create both variants so
    you can do

    obj.a # getter
    obj.a = 10 # setter
    obj.a(10) # setter

    Kind regards

    robert

    --
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Oct 24, 2009
    #7
    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. =?Utf-8?B?S2V2aW4gQnVydG9u?=

    Pre-Send Request Headers, Pre-Send Request Content

    =?Utf-8?B?S2V2aW4gQnVydG9u?=, Dec 31, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    1,107
    =?Utf-8?B?S2V2aW4gQnVydG9u?=
    Dec 31, 2004
  2. Nathan Sokalski
    Replies:
    3
    Views:
    1,973
    Larry Lard
    Nov 23, 2005
  3. Guest
    Replies:
    6
    Views:
    395
    Guest
    Sep 4, 2007
  4. Chris Reay

    Does Socket.send send all bytes?

    Chris Reay, Nov 3, 2003, in forum: Ruby
    Replies:
    2
    Views:
    230
    Chris Reay
    Nov 4, 2003
  5. Replies:
    3
    Views:
    182
    Jeremy McAnally
    Jan 31, 2008
Loading...

Share This Page