Maybe my brain is broken, but when using blocks in Ruby, I keep wanting to have access to the scope of the calling object:
class Foo
def bar
baz = "qux"
yield
end
end
>> Foo.new.bar { puts baz }
NameError: undefined local variable or method `baz' for main:Object
Which makes sense, of course. But what if I really needed to know what baz was, in the context of the block? (Assume that I'm determining my accessing needs at runtime, and can't add arguments willy-nilly to the yield call). The solution I came up with was to use yield(self). It seems kind of dirty, and it is- but it works. Mostly.
class Foo
attr_accessor :accessible_baz
def bar
baz = "qux"
@instance_baz = "qux"
@accessible_baz = "qux"
yield(self)
end
end
#Attempt to get the local variable
>> Foo.new.bar {|container| puts container.baz }
NameError: undefined local variable or method `baz' for main:Object
#Attempt to get an instance variable without an accessor
>> Foo.new.bar {|container| puts container.instance_baz }
NoMethodError: undefined method `instance_baz' for #
>> Foo.new.bar {|container| puts container.instance_variable_get(:@instance_baz) }
qux
#Attempt to get an instance variable with an accessor
>> Foo.new.bar {|container| puts container.accessible_baz }
qux
I think this might be an OK solution if you're just trying to get at methods or accessible instance variables of the calling object, but I'm not sure it is worth it to go through instance_variable_get in order to get other instance variables. Is there a better way to get at this stuff? Any method that is more elegant?