[Note: parts of this message were removed to make it a legal post.]
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