Binding in ruby1.9

Could someone explain why this code does not work in ruby1.9 and
possibly provide a workaround. The end goal is to be able to pass a
binding to an ERb result method that provides a limited set of
variables to the ERb template evaluation.

cat a.rb

obj = Object.new
class << obj
attr_accessor :foo
end
obj.foo = ‘the foo method’
eval “puts foo”, obj.send(:binding)

ruby a.rb
the foo method

ruby1.9 a.rb
a.rb:7:in eval': undefined local variable or methodfoo’ for
main:Object (NameError)
from a.rb:7:in eval' from a.rb:7:in

ruby1.9 --version
ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-darwin9.6.0]

Blessings,
TwP

Tim P. wrote:

end
obj.foo = ‘the foo method’
eval “puts foo”, obj.send(:binding)

What an unusual feature to keep coming up.

The contract of binding is that it returns a reification of the caller’s
binding. Under 1.8, however, the behavior acted a bit differently, using
the “self” that binding was actually called against. 1.9 has largely
remedied this by always returning the binding of the caller, even if you
send(:binding) to another object.

I believe instance_evaling “binding” against the target object would
give you the behavior you’re looking for:

[headius @ cnutter:~/projects/ruby-benchmark-suite]
â—† ruby -e “o = Object.new; p o; eval ‘p self’, o.send(:binding)”
#Object:0x29414
#Object:0x29414
[headius @ cnutter:~/projects/ruby-benchmark-suite]
â—† ruby1.9 -e “o = Object.new; p o; eval ‘p self’, o.send(:binding)”
#Object:0x3e736c
main
[headius @ cnutter:~/projects/ruby-benchmark-suite]
â—† ruby1.9 -e “o = Object.new; p o; eval ‘p self’,
o.instance_eval{binding}”
#Object:0x3e72a4
#Object:0x3e72a4

  • Charlie

On Jan 30, 2009, at 12:56 PM, Charles Oliver N. wrote:

obj.foo = ‘the foo method’

Okay, that explanation makes sense. My new implementation (following
along with the Kernel docs)

cat a.rb
obj = Object.new
class << obj
attr_accessor :foo
def get_binding() binding; end
end
obj.foo = ‘the foo method’
eval “puts foo”, obj.get_binding

ruby1.9 a.rb
the foo method

Thanks for the insight.

Blessings,
TwP

Tim P. wrote:

eval “puts foo”, obj.get_binding

ruby1.9 a.rb
the foo method

Even better!

  • Charlie