# What does this statement do?

**URL:** <https://www.ruby-forum.com/t/what-does-this-statement-do/161795>\
**Category:** Ruby\
**Created:** [March 2, 2009, 3:04pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795 "2009-03-02T15:04:36Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 3:04pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/1 "2009-03-02T15:04:36Z")

</div>

Hi Guys,

I have been wondering what does this statement do and what does it set.  
It interferes with my methods\_missing handler:

{code}  
class MyClass

something = “something else”

end  
{code}

---

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 3:20pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/2 "2009-03-02T15:20:07Z")

</div>

Stanislaw W. wrote:

> Hi Guys,
> 
> I have been wondering what does this statement do and what does it set.  
> It interferes with my methods\_missing handler:
> 
> {code}  
> class MyClass
> 
> something = “something else”
> 
> end  
> {code}

I guess this is assigning a string to a variable that is created in the  
MyClass scope. But my problem is that I have some setter methods that  
I’m using through method\_missing, but method\_missing is never triggered  
because it is assigning stuff just like in the example above.

---

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 3:25pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/3 "2009-03-02T15:25:01Z")

</div>

Stanislaw W. wrote:

> > end  
> > {code}
> 
> I guess this is assigning a string to a variable that is created in the  
> MyClass scope. But my problem is that I have some setter methods that  
> I’m using through method\_missing, but method\_missing is never triggered  
> because it is assigning stuff just like in the example above.

You’re saying that “something” is supposed to be treated like a method  
instead of like a variable? Try

self.something = “something else”

---

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 3:29pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/4 "2009-03-02T15:29:43Z")

</div>

On Mon, Mar 2, 2009 at 9:18 AM, Stanislaw W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> >

That statement is the same as calling MyClass.something=(“something  
else”)

If you want method\_missing to catch it, you need to define a  
method\_missing on the class itself, like this:

class MyClass

def self.method\_missing(name, \*args)  
end

end

Jason

---

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 3:54pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/5 "2009-03-02T15:54:39Z")

</div>

On Mon, Mar 2, 2009 at 9:31 AM, Stanislaw W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> self.class.method(name).call args  
> set\_field = value  
> end
> 
> end
> 
> B.my\_method

Yes this is a well-known ruby newbie gotcha.

Because the Ruby syntax allows simple names to refer to either a local  
variable or a method invocation, there are some times when things get  
ambiguous.

In the case of a name on the right hand side of an assignment, or  
equivalent  
settings, the ruby compiler treats the name as a local variable if the  
name  
has already been assigned a value, and as a method call with an implied  
receiver of self otherwise.

In the case of a name on the right hand side, it treats the name as a  
local  
variable, and assigns it a value.

You HAVE to explicitly give a receiver of self when invoking an  
attribute  
setter method in ruby. So in my\_method you have to use self.set\_field =  
value.

And this is why, for those who like to mark methods as private.

class Foo

private  
def a=(value)  
…  
end

def b  
…  
end

## public def c self.a= 2 # This is okay self.b # This triggers a NoMethodError "private method ‘b’ called for … end end

Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 3:57pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/6 "2009-03-02T15:57:04Z")

</div>

Thanks Rick,

This is clear explanation. Makes sense…

---

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 3:32pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/7 "2009-03-02T15:32:32Z")

</div>

Ok, this is the example I want to get to work. Method set\_field is never  
triggered because local variable set\_field is being set.

class A

def self.set\_field=(value)  
puts “Trying to set field value”  
end

def method\_missing(name, \*args)  
self.class.method(name).call args  
end  
def self.method\_missing(name, \*args)  
new.method(name).call args  
end

end

class B \< A

def my\_method(value)  
set\_field = value  
end

end

B.my\_method

---

<div class="post-metadata">

**Author:** ![swozniak](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e9a140/32.png) [@swozniak](https://www.ruby-forum.com/u/swozniak)\
**Post date:** [March 2, 2009, 6:15pm UTC](https://www.ruby-forum.com/t/what-does-this-statement-do/161795/8 "2009-03-02T18:15:54Z")

</div>

On 02.03.2009 15:27, Jason R. wrote:

> > > something = “something else”
> 
> That statement is the same as calling MyClass.something=(“something else”)

Actually, no. See Rick’s excellent explanation. For test addicts:

[oracle@ora01 ~]$ ruby y.rb  
test 1  
foo called with 123  
test 2  
[oracle@ora01 ~]$ cat y.rb

class X  
def self.foo=(a)  
printf “foo called with %p\n”, a  
end  
end

puts “test 1”  
X.foo = 123

class X  
puts “test 2”  
foo = 987  
end

[oracle@ora01 ~]$

> If you want method\_missing to catch it, you need to define a  
> method\_missing on the class itself, like this:
> 
> class MyClass
> 
> def self.method\_missing(name, \*args)  
> end
> 
> end

Won’t help here, because the statement is interpreted as a local  
variable assignment.

Kind regards

robert
