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

In a couple scripts I've read lately I've seen some labeled blocks like so:
# Declare some globals. Conf: { # Set up the globals. } Exec: { # Body of the script goes here. } # Maybe some subs defined down here.

What's the point of labeling these blocks?

I'm familiar with labeling for/while loop blocks for the purpose of controlling execution of an outer one from an inner one. I've also seen naked unlabeled blocks used for creating a local scope.

Maybe the author of such labeled blocks is just using the label in lieu of a comment?

Replies are listed 'Best First'.
Re: What's the point of a labeled block without a loop?
by Ovid (Cardinal) on Dec 16, 2005 at 22:04 UTC

    Some folks like to use labeled blocks as an odd form of commenting. However, if you look at how Test::More implements SKIP blocks, you'll be rather horrified at the how it works :) (if the SKIP value is true, there's a last SKIP call).

    sub skip { my($why, $how_many) = @_; my $tb = Test::More->builder; unless( defined $how_many ) { # $how_many can only be avoided when no_plan is in use. _carp "skip() needs to know \$how_many tests are in the block" unless $tb->has_plan eq 'no_plan'; $how_many = 1; } for( 1..$how_many ) { $tb->skip($why); } local $^W = 0; last SKIP; }

    That relies on the SKIP label in the test, even though you don't see the last call.

    Cheers,
    Ovid

    New address of my CGI Course.

      Egads.

      Although I haven't looked inside Test::More, I think I see what you're talking about. I tried this:

      #!/usr/bin/perl use warnings; use strict; sub tear_us_outta_here { print "Getting out of loop labeled FOO.\n"; last FOO; } FOO: for ( 1 .. 10 ) { print "At $_.\n"; if ( $_ == 4 ) { tear_us_outta_here(); } }
      ~~~ yields ~~~
      At 1. At 2. At 3. At 4. Getting out of loop labeled FOO. Exiting subroutine via last at ./foo.pl line 8.
      That looks kinda' weird and scary to me... :)

      Heh,.. for this sort of stuff, we should have a Halloween Perl-ghost-story-hour every October:

      {dark room with flashlight shining up on an upright dead-tree printout of some code}:
      "On this very line of code, many iterations ago, for no apparent reason, the loop... abruptly ended! Some say it was a hardware failure, others suggest deep magic at work in the bowels of the interpreter..."
      ;)

      EDIT: Thanks for all the replies and interesting suggestions folks. Seems like, as Ovid suggests, the original author of the code I'm looking at just used the labels as some off form of odd commenting -- especially considering that there isn't any pod in the code.

Re: What's the point of a labeled block without a loop?
by QM (Parson) on Dec 16, 2005 at 23:19 UTC
    It's also handy to limit the scope of the block internals, such as a closure:
    Checker: { my %seen; sub Checker { my $value = shift; if (defined($seen{$value})) { return $value; } else { $seen{$value} = 1; return; } } }
    This could also be used as a bookmark for editors, assuming care was used in choosing unique labels.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Re: What's the point of a labeled block without a loop?
by dragonchild (Archbishop) on Dec 16, 2005 at 23:36 UTC
    I use it sometimes for processing STDIN (the few times I ever need to). redo is your friend.
    my $age; INPUT: { print "Please enter your age: "; $age = <STDIN>; if ( $age !~ /\D/ ) { last INPUT; } redo INPUT; }

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      Is there any specific advantage to the label there?

      That appears to work just as well with none (except you need a chomp).

      I'm not much taken with "if $age does not contain a non-digit, were done". How about:

      my $age; { print "Please enter your age: "; chomp( $age = <STDIN> ); redo if $age =~ /\D/; } Please enter your age: Mind your own Please enter your age: As old as m'tongue and a little older than m'teeth. Please enter your age: 300000000000

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        The only real benefit is reader clarity. By labelling it, you're giving a reason for a bare-block.

        Also, my personal style - I (mostly) always put a label with every last and redo. (I don't for next because next is much more common.)


        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: What's the point of a labeled block without a loop?
by Hue-Bond (Priest) on Dec 16, 2005 at 22:34 UTC

    They can be used as a target for the goto function:

    abc: { sleep 1; print "japh\n"; } goto abc;

    --
    David Serrano

Re: What's the point of a labeled block without a loop?
by badaiaqrandista (Pilgrim) on Dec 16, 2005 at 22:23 UTC
    Sometime, I use it to implement 'switch':
    SWITCH: { if (...) { ..... ; last SWITCH } elsif (...) { ..... ; last SWITCH } elsif (...) { ..... ; last SWITCH } }

      If you use elsif, what's the point of the last statements?

        it's there for consistency's sake only because I am obsessed with it... :D you can leave it out, but if you want to add more elsif, you have to remember to put 'last SWITCH' on that block... saving me from future bugs :D

        --------------
        badaiaqrandista