# Setting attribute via send in Ruby 1.8.6

**URL:** <https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782>\
**Category:** Ruby\
**Created:** [October 23, 2009, 5:15pm UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782 "2009-10-23T17:15:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmcfab](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/838e76/32.png) [@cmcfab](https://www.ruby-forum.com/u/cmcfab)\
**Post date:** [October 23, 2009, 5:15pm UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782/1 "2009-10-23T17:15:40Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![cmcfab](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/838e76/32.png) [@cmcfab](https://www.ruby-forum.com/u/cmcfab)\
**Post date:** [October 23, 2009, 5:19pm UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782/2 "2009-10-23T17:19:46Z")

</div>

On Friday 23 October 2009, Charles C. wrote:

> | attr\_writer :foo  
> |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

---

<div class="post-metadata">

**Author:** ![cmcfab](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/838e76/32.png) [@cmcfab](https://www.ruby-forum.com/u/cmcfab)\
**Post date:** [October 23, 2009, 6:40pm UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782/3 "2009-10-23T18:40:34Z")

</div>

On Fri, 23 Oct 2009 17:18:22 +0200, Robert K.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote in  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> On 10/23/2009 05:10 PM, Charles C. 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.

---

<div class="post-metadata">

**Author:** ![cmcfab](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/838e76/32.png) [@cmcfab](https://www.ruby-forum.com/u/cmcfab)\
**Post date:** [October 24, 2009, 9:06am UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782/4 "2009-10-24T09:06:52Z")

</div>

On Fri, Oct 23, 2009 at 6:40 PM, Charles C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > …  
> > 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)

Jesus.

---

<div class="post-metadata">

**Author:** ![cmcfab](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/838e76/32.png) [@cmcfab](https://www.ruby-forum.com/u/cmcfab)\
**Post date:** [October 23, 2009, 5:20pm UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782/5 "2009-10-23T17:20:56Z")

</div>

On 10/23/2009 05:10 PM, Charles C. wrote:

> attr\_writer :foo  
> 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

---

<div class="post-metadata">

**Author:** ![cmcfab](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/838e76/32.png) [@cmcfab](https://www.ruby-forum.com/u/cmcfab)\
**Post date:** [October 24, 2009, 11:05am UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782/6 "2009-10-24T11:05:41Z")

</div>

On 10/24/2009 09:06 AM, Jesús Gabriel y Galán wrote:

> > > > nothing, most likely because I’m using the wrong search terms.  
> > > > The suspense almost killed me!  
> > > > I’m glad I did not extend the pause even more. 🙂

> You can achieve what you want if instead of using attr\_writer you roll your own.  
> 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

---

<div class="post-metadata">

**Author:** ![cmcfab](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/838e76/32.png) [@cmcfab](https://www.ruby-forum.com/u/cmcfab)\
**Post date:** [October 24, 2009, 10:33am UTC](https://www.ruby-forum.com/t/setting-attribute-via-send-in-ruby-1-8-6/177782/7 "2009-10-24T10:33:59Z")

</div>

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
