From: Rick DeNatale Date: 2009-03-02T23:52:16+09:00 Subject: Re: What does this statement do? --001636163d193ef5d2046423fb50 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On Mon, Mar 2, 2009 at 9:31 AM, Stanislaw Wozniak wrote: > 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 > 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/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale --001636163d193ef5d2046423fb50--