About

James Golick

James Golick is an engineer, entrepreneur, speaker, and above all else, a grinder.

As CTO (or something?) of BitLove, he scaled FetLife.com's traffic by more than an order of magnitude (and counting).

James spends most of his time writing ruby and scala, building infrastructure, and extinguishing fires.

He speaks regularly at conferences and blogs periodically, but James values shipping code over just about anything else.

Latest Tweets

follow me on Twitter

James on the Web

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"