Stefan Kaes
3/15/2005 4:18:00 PM
Yukihiro Matsumoto wrote:
>Hi,
>
>In message "Re: eval/binding question"
> on Tue, 15 Mar 2005 23:02:44 +0900, Stefan Kaes <skaes@gmx.net> 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?