Constant lookup and blocks
class HelperHandler def foo_exists Foo.exists end module Foo def self.exists puts "Foo does indeed exist" end end end h = HelperHandler.new h.foo_exists # => "Foo does indeed exist"
No surprises here. This, however, is quite surprising:
class HelperHandler def initialize(&block) instance_eval(&block) end end HelperHandler.new do foo_exists # => "Foo does indeed exist" Foo.exists # => NameError: uninitialized constant Foo end
instance_eval is quite common in Ruby libraries. Sinatra, for example, which is what this website is built on, uses it. It evals the block in the context of the instance in question.
Calling the method worked, but referring to the
Foo constant is not OK.
That's because Ruby doesn't care about
instance_eval when it comes to constants. Constants are looked up in the calling scope. Nothing you can do about it.
Unless you want to be evil and use strings.
class HelperHandler def initialize(evil) eval(evil) end end HelperHandler.new "Foo.exists" # => Foo does indeed exist
Questions or comments?