Uri Guttman <[EMAIL PROTECTED]>:
> another bad point about eval is that it can access and modify lexicals
> and globals anywhere in the code. so that can lead to action at a
> distance and very hard to find bugs.
Ben Tilly <[EMAIL PROTECTED]> wrote:
> sub foo {
> my $x = 7;
> my $generator = make_generator(q{++$x}};
> print $generator->() for 1..5;
> }
>
> sub make_generator {
> my $action = shift;
> my $x = 11;
> eval qq{
> sub {
> # Some interesting code here...
> $action;
> }
> };
> }
>
> [...]
>
> I agree that Perl's behaviour is logical. However it is
> inconvenient. And from the point of the person who is
> trying to use make_generator, it causes internal details
> to matter too much.
Hi, Ben and all. I agree that using eval here is wrong. But I still
don't see action at a distance.
The problem in this example is that make_generator doesn't make a
generator. Rather it creates a sub in its own context using code passed
in as a string. The passed-in code can manipulate a unique variable "$x"
common between all the returned subs. It instantiates a dynamic method
that can use a private member "$x," which is one of the things eval() is
actually good for.
> A workaround, of course, is to tell the person to use
> global variables.
What's wrong with the following?
sub foo {
my $x = 7;
my $generator = sub{++$x};
print $generator->() for 1..5;
}
Note that $generator can be passed around and invoked from anywhere
anyplace in the code with the same result. It is a true coroutine, which
I assume is what you wanted.
-TimK
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm