From: Stefan Kaes Date: 2005-03-16T01:17:55+09:00 Subject: Re: eval/binding question Yukihiro Matsumoto wrote: >Hi, > >In message "Re: eval/binding question" > on Tue, 15 Mar 2005 23:02:44 +0900, Stefan Kaes writes: > >|I tried to create local variables from a name=>value hash passed as a >|parameter, but I can't get it to work. The following test program shows >|what is happening: > >local variables should be determined at compile time, thus local >variables defined first in the eval'ed string, can only be accessed from >other eval'ed strings. In addition, they will be more ephemeral in >Ruby2, so that these variables will not be accessed from outside. > > Well, I don't agree. From a language designers point of view x=5 and eval "x=5" should do the same thing: modify the current binding by introducing a new value-binding with name x and value 5. I don't know of any language which behaves differently (e.g. LISP works like this AFAIK). Of course, as a compiler writer, one might prefer to be able to determine all local variables by looking at the source. But this is just a wish to make the compiler simpler or enable better optimization. >In summary, I recommend you not to use local variables for your >purpose. They are wrong tool for it. > > matz. > Maybe I should explain why I tried this: when using ERB one can compile a template into source, which can then be eval'ed using eval. Local variables for use in the template can be set up using the sort of eval given in my example. However, in this case the 'compiled' template code gets reparsed on each evaluation of the template code. I wanted to speed up this process by defining a function (eval "def fun; #{src}; end", aBinding), thereby pasring the code only once. This works pretty well and gives about 25% increase in speed. The performance gain will be much bigger, once ruby gets a real JIT. But, as it turned out, local variables are not accessible when the defined function is executed. I saw two solutions: First, change the local variables to instance variables on the class executing the function. This works, but does not feel right (name space pollution). Second, put all locals in an instance hash and set up local functions inside the defined function from the hash. Which does not work. Any other ideas?