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 method `foo' for main:Object (NameError)
from a.rb:7:in `eval'
from a.rb:7:in `<main>'
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)
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>
[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>
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)
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.
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
···
On Jan 30, 2009, at 12:56 PM, Charles Oliver Nutter wrote: