Maintaining local variables between eval code

Consider the following Ruby code:

class Foo def bar; 42; end def run(code1,code2) binding.eval(code1,'c1') binding.eval(code2,'c2') end end Foo.new.run "x=bar ; px", "px" 

The goal is to dynamically evaluate some code that creates local variables, and then run additional code that has access to these variables. Result:

 c2:1:in `run': undefined local variable or method `x' for #<Foo:…> (NameError) 

Note that the above will only work if eval mutates the binding, which it only does when changing existing local variables, and not when creating new variables. I don’t have to (or need) every run to mutate an external binding, I just need to have access to the previous binding for subsequent code evaluations.

How can I define two blocks of code and maintain local variables between them?


For a curious, real-world application of this is a custom tool that can execute a script file, and then go to REPL. I want the REPL to have access to all local variables created by the script file.

+1
source share
1 answer

You need to save the Binding and reuse the same one. If you re-name Binding - even in the same area - you will get a new binding. So, for the demo function, we can do this:

 class Foo def initialize; @b = binding; end def bar; 42; end def run(code) @b.eval( code, '(yourcode)' ) end end f = Foo.new f.run "x=bar ; px" #=> 42 f.run "px" #=> 42 
+1
source

Source: https://habr.com/ru/post/1206466/


All Articles