Charles Oliver Nutter
1/12/2009 3:27:00 AM
Ken Bloom wrote:
> Second, the trace function is only being used for a couple of calls
> before the continuation is called, and execution jumps back into
> Binding.of_caller at which point the trace function is removed. It
> wouldn't appear to me like it would hurt things too much. (Maybe it
> requires turning on an otherwise disabled feature in JRuby?)
Tracing works, but JRuby and IronRuby do not support continuations, and
I think they work differently in 1.9. It's a hack that's unlikely to
work reliably, even across minor versions of a given implementation.
In general I think Binding.of_caller is a really, really bad idea
because it exposes internal details every method call in *your* code to
the whims of *someone else's* code. Basically, it breaks the most sacred
encapsulation possible, a method call's local variables.
Imagine a case like this:
def secure_action(encrypted_password)
decrypted_password = decrypt(encrypted_password)
authorize(decrypted_password)
do_secure_task
end
If it were possible to modify do_secure task, or if you were simply
calling a third-party library, it could access the runtime variables of
the caller:
def do_secure_task
binding = Binding.of_caller
vars = eval 'local_variables', binding
vars.each do |name|
if name =~ /password/
use_for_evil(eval name, binding)
end
end
end
I even implemented Binding.of_caller for fun once in JRuby, and removed
it when I realized how invasive and dangerous it was.
Just like retry was limited in 1.9 to restarting a rescued block of code
(rather than being able to reevaluate the original arguments and
receiver), Binding.of_caller should remain unsupported.
- Charlie