b4swine has asked for the wisdom of the Perl Monks concerning the following question:

The manual (perl sytanx) says:

The LABEL identifies the loop for the loop control statements next, last, and redo. If the LABEL is omitted, the loop control statement refers to the innermost enclosing loop. This may include dynamically looking back your call-stack at run time to find the LABEL. Such desperate behavior triggers a warning if you use the use warnings pragma or the -w flag.

Can someone explain? What is this desperate behavior? I feel very uncomfortable when I read a sentence that makes no sense to me. An example would be most appreciated.

Replies are listed 'Best First'.
Re: Desparate behavior in loop labels
by GrandFather (Saint) on Aug 29, 2007 at 03:00 UTC
    use warnings; use strict; quit: for (1 .. 10) { check_early ($_); } sub check_early { my $value = shift; last quit if $value == 5; print "$value\n"; }

    Prints:

    1 Exiting subroutine via last at noname1.pl line 11. 2 3 4 Exiting subroutine via last at noname1.pl line 11.

    DWIM is Perl's answer to Gödel
      Thanks for the example.

      BTW it was very puzzling, until I replaced the print with a print STDERR which then prints immediately. Otherwise the 'Exiting...' message before line 2 is very confusing.

      Just to make sure that I understand what is going on:

      The "last LABEL" (in this case "quit") looks around locally for the label, and doesn't find it. It then jumps back through the stack to look for the label, and drops a warning when it does so?

      I'd no idea that was possible. It sounds a little wonky, honestly, but I guess that's why it tosses a warning.

        I think you've hit the nail on the head there.

        Contorted control flow can sometimes be handy, but as it can lead to a maintenance nightmare it deserves a warning.

        Perhaps more importantly, there's probably some history to why last works that way in Perl, too. Raising the warning and providing the former functionality rather than breaking the functionality is a good compromise for features that have been declared as questionable practice.

        Update: s/questionably/questionable/; to clarify that last sentence a bit.

Re: Desparate behavior in loop labels
by Errto (Vicar) on Aug 29, 2007 at 03:05 UTC
    Here is an example:
    sub foo { print $_; last if $_ >= 3; } sub bar { for (1 .. 10) { foo; } } bar;
    This script will stop printing after "3". This is because calling last from inside foo jumps out of the loop it's in, even though that loop is defined in bar. By contrast, in languages like C or Java, the equivalent calls (break and continue) are simply illegal outside loops.
Re: Desparate behavior in loop labels
by lodin (Hermit) on Aug 29, 2007 at 03:05 UTC

    I think this may be an example:

    sub foo { last } { foo(); } __END__ Exiting subroutine via last at ...

    lodin