Ruby 1.8.5 *_eval Methods are subject to access modifiers on self!
Sep 28, 2007
Since we're running CentOS5 on our svn/CC.rb server. There are no packages for Ruby 1.8.6, so naturally, I just went with the v1.8.5 install. Everything was working great, until I came across this gotcha. Since I can't seem to find anything documented anywhere, hopefully other people will be able to find this article, when they google for it.
In ruby 1.8.5, self, in an instance_eval block, is subject to the same access modifiers as any old instance variable. Protected, and private methods raise "NoMethodError: protected/private method `x' called for ...". Luckily, though, the send(:method_name) hack still works to get around any access modifier. So, if you need to get your code running on 1.8.5, that's the workaround.
class Person
protected
def something_secret
"don't tell anybody"
end
private
def something_really_secret
"REALLY don't tell anybody"
end
end
## Ruby 1.8.5
person.instance_eval { self.something_secret } # NoMethodError: protected method `something_secret' called for ...
person.instance_eval { self.something_really_secret } # NoMethodError: protected method `something_really_secret' called for ...
person.send :something_secret # "don't tell anybody"
person.send :something_really_secret # "REALLY don't tell anybody"
## Ruby 1.8.6
person.instance_eval { self.something_secret } # "don't tell anybody"
person.instance_eval { self.something_really_secret } # "REALLY don't tell anybody"
person.send :something_secret # "don't tell anybody"
person.send :something_really_secret # "REALLY don't tell anybody"