Module_eval, scope, __FILE__ and __LINE__

(Florian G. Pflug) #1


In my application and I need some variation of “attr_accessor” and the like,
so I wrote class functions that create special getter and setter methods
on-the-fly, using module_eval.

If the code I evaled fails during execution (not during
compilation/evaling), the backtrace doesn’t show the filename, and gives a
line number relative to the start of the eval, not the start of the file.

Today I realized that I can “fix” this by doing

_f,_l=FILE,LINE; module_eval %{
…long block of code…
…even more code…
}, _f, _l

instead of plain

module_eval %{
…long block of code…
…even more code…

(The reason I use %{} instead of {} is that I use #{} in the evaled
string, just in case someone wonders)

Now, this solves my problem but looks kind of ugly, so I wanted to move it
to a library, and did the following

class Module
def module_eval_withcontext(str)
module_eval(str, FILE, LINE)

But this has slighly different semantics, because the lexical scope of the
eval has changed, so local variables defined around the place where
module_eval_withcontext is called are no longer available in the evaled

This made me wonder how module_eval works, when it is passed a string
instead of a block. It seems to do the Right Thing, but seems to use some
sort of magic - it seems as if the evaled string would magically be
connected to a binding which is used for evaling…

Could anyone shed light on this, and tell me if there is a way to wrap

greetings, Florian Pflug

PS: I believe it would be a good idea to make module_eval default to FILE and LINE
if no second and third parameter is passed…