Ben Tilly wrote:
>> I agree that using eval here is wrong. But I still
>> don't see action at a distance.
>
> You can argue about whether it is action at a distance, but you
> have tight coupling between the internals of make_generator
> and the string passed into it that was generated from very far
> away.
Correct. A function that uses eval() does so in its own context. I don't
see what makes this a problem with eval(). Rather, it's a concern that
affects the software design.
>> The problem in this example is that make_generator doesn't make a
>> generator.
>
> I know full well what the problem is. And the result is that you
> cannot consider using code generation for a situation like this.
Not if you want to make a generator as you have tried, no. My point was
that this is not a problem with eval(); it's a problem with your
proposed design.
I use eval() when I don't know what the code is until runtime, or to
execute code generated in one place in a context generated from another.
But I can't recall a case like the latter that wasn't also an instance
of the former.
>> sub foo {
>> my $x = 7;
>> my $generator = sub{++$x};
>> print $generator->() for 1..5;
>> }
>
> But in general you're now
> prevented from adding various kinds of syntactic sugar,
> manipulating the passed in code before compiling it, etc.
If you really need to manipulate the code, you apply the syntactic sugar
when generating the code string. Then you invoke eval() in whatever
context the code should execute.
Or alternatively, you can pass to the code-generator an evaluation
context that the generated code will use. One might use a technique like
this when using Perl as a scripting language within a Perl program, for
example.
>> Note that $generator... is a true coroutine.
>
> It is not a coroutine. It is a closure.
It is both a closure and a coroutine.
-TimK
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm