"Randal L. Schwartz" wrote:

> how do you indicate with 'last' that you
> want a false return, or a true return?  This never comes up with a do
> {} block, or a subroutine block, because while those are being
> evaluated for a value, they don't respect last/next/redo.

if "last" means, return the most recently evaluated expression as
a return value and do not re-enter the block, the various semantics
can be created with a comma.



>Your
> request to have the grep block understand 'last' was the first block
> in Perl history that would have simultaneously needed to exit early
> *with* a value.  And we hadn't come around that block yet. :)
> 
> We really need a clean way to distinguish those four cases:
> 
>     "yes" and keep going
>     "no" and keep going
>     "yes" and abort after this one
        ($FirstSmall) = grep { $_ <= 7 and last } @numbers; # already true

>     "no" and abort after this one
        my $count;
        # minor chicanery required to force short-circuit with false result
        @Smalls_in_first_five = 
                grep { $count++ < 5 ? ($_ <= 7) : (0,last)} @numbers;



I see C<last> in grep/map as implicitly setting a gatekeeping variable which
would prevent the remainder of the data from being evaluated.  Since this is
known, evaluation of the remainder of the data can be safely optimised away.


Using the "gatekeeper" idea without C<last> we get these:


>     "yes" and abort after this one
        my $gatekeeper = 1;
        ($FirstSmall) = grep
                { $gatekeeper and $_ <= 7 and ($gatekeeper = 0), 1 } @numbers; 

>     "no" and abort after this one
        my $count;
        my $gk = 1;
        @smalls_in_first_five = grep
                {$gk and ($count++ < 5 ? ($_ <= 7) : $gk=0 )} @numbers;


-- 
                          David Nicol 816.235.1187 [EMAIL PROTECTED]
           perl -e'map{sleep print$w[rand@w]}@w=<>' ~/nsmail/Inbox

Reply via email to