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

I have used labels before in loops only.. such as...
LINE: for ($i=0; defined($i); $i++) { flock(FILE,2) or next LINE; }

Do you have to use lables with loops only? or can I do something like...
LINE: flock(FILE,2) or goto LINE;
Would this preform the same thing? Does anyone know where I could read up on labels and stuff? Thanks monks.

Replies are listed 'Best First'.
Re: How to use Labels
by Hofmator (Curate) on Jun 19, 2001 at 19:01 UTC

    I'm not so sure what the use of your construct is, but you can use labels on single lines:

    LOOP: print "Good old infinite loop\n"; goto LOOP;

    For more on labels (and other stuff) see perlsyn.

    -- Hofmator

Re: How to use Labels
by Abigail (Deacon) on Jun 20, 2001 at 03:01 UTC
    The issue of using lables has already been addressed, but I am wondering, why are you repeatedly trying to flock the same file, without even inspecting (and correcting!) why the lock failed?

    Are you under the assumption that if the file is already locked, flock will return with a false value? Because that is not the case. flock will block until it gets the lock. It will return only in rare cases, like the OS being out of resources. Trying to lock again in a tight loop isn't going to solve that problem! The flock also fails if the filehandle isn't open, and then it will keep failing!

    -- Abigail

Re: How to use Labels
by VSarkiss (Monsignor) on Jun 19, 2001 at 18:58 UTC
    A label can be placed on any basic BLOCK, or any of the looping statements (while, for, and foreach). The "Compound Statements" section in perlsyn has the details. So, no, you can't do this: LINE: flock(FILE, 2) or goto LINE; You could do it enclosing the statement in curly braces to make a block, but that whole statement horrifies me so much that I'm not going to show you how. ;-)

    BTW, labelled blocks are one way you can create "switch" statements in Perl. Continue down perlsyn to the section named "Basic BLOCKs and Switch Statements" for several examples.

    HTH

    Updated by VSarkiss:
    My bad. Hofmator is right. You can put labels on single statements like your example. I need to test before I hit "submit"....

      So, no, you can't do this: LINE: flock(FILE, 2) or goto LINE;

      Why not? Try this out and see what it prints:

      $i = 5; LINE: print "got here\n"; --$i and goto LINE;

      The 15 year old, freshman programmer,
      Stephen Rawls

Re: How to use Labels
by arturo (Vicar) on Jun 19, 2001 at 21:31 UTC

    Apart from the technical issue, the algorithm is just asking for trouble. Take a look at a 'naked block' and use redo. Put a # of tries limit on your loop:

    my ($tries, $success) = (0, 0); { last if ++$tries > 10; print "Flocking file: attempt # $tries ... \n"; # attempts to flock file, prints a warning if that fails # warning -- the following relies on operator # precedence (&& binds tighter than or -- # use parens if that might confuse you) flock(FILE, 2) or warn "Can't flock file: $!\n" && redo; # rest of stuff $success =1; } die "Gave up after", --$tries, " attempts." unless $success;

    HTH

    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'

      I don't really like last, redo, and next much. They have many of the same problems that lead people to complain so much about goto but they also are worse than goto in that it can take quite a bit of parsing (by the human reading the code) to figure out where they are transfering control to. You have to keep parsing past enclosing braces deciding whether each is the kind of "block" that these affect or not.

      So if you are going to use them, please use them as little as possible and try not to hide them in the code. I've experimented with out-denting these types of constructs but only very rarely find that more than marginally effective.

      So I have two big gripes with the above code. First, putting a last at the very top (or bottom) of the block is just obfuscation. Change that to: while(  ++$tries <= 10  ) { Second, your redo is quite well hidden! I'd much rather have the conditional nature of the execution of the $success= 1; line more obvious.

      How about this?

      do { if( 0 < $tries++ ) { warn "Can't flock file: $!\n"; } elsif( 10 < $tries ) { die "Gave up trying to lock file.\n"; } warn "Locking file (attempt $tries)...\n"; } while( ! flock(FILE,2) ); # Success!

              - tye (but my friends call me "Tye")
Re: How to use Labels
by dimmesdale (Friar) on Jun 19, 2001 at 19:01 UTC
    To allow for labels you need to block off the code(because I assume you don't wish it for the entire script; but if you did, you still need brackets). This would work for our example:
    LINE: { flock(FILE,2) or goto LINE; } #p.s., you should probably #use the constants provided #and not numbers like 2

    Update: Yes, labels on single lines can be used. However, in practise, a looping construct(for,while,etc.) is usually better for only a single line. Even then, though, having brackets is best to solve any abiguity that may arise. But yes, a single line label is possible(and useful on some occasions).