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
Boston-pm@mail.pm.org
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to