John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

When can you use a naked block, and when do you put "do" in front of it?

Replies are listed 'Best First'.
Re: {} vs do{}
by MeowChow (Vicar) on Jul 04, 2001 at 08:31 UTC
    do BLOCK and naked BLOCK's are completely unrelated. The documentation for do BLOCK is illuminating:
    Not really a function. Returns the value of the last command in the se +quence of commands indicated by BLOCK. When modified by a loop modifier, executes the BLO +CK once before testing the loop condition. (On other statements the loop modifiers test the c +onditional first.) do BLOCK does not count as a loop, so the loop control statements next +, last, or redo cannot be used to leave or restart the block. See the perlsyn manpage for alt +ernative strategies.
    Naked BLOCK's on the other hand do not return values, cannot be used with loop modifiers, but can use loop control statements. Both naked BLOCK's and do BLOCK establish a new lexical scope within the BLOCK, however.

       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print

      Hmmmm ... what about this:

      open( FH1 , '>foo' ); open( FH2 , '>bar' ); @fhs = ( FH1 , FH2 ); print { $fhs[ $_ % 2 ] } "$_\n" for ( 1 .. 10 );
      which does actually put odds in one file and evens in another.

      I understood this as the BLOCK returning the last value. Is something else going on?

      Scott 'Confused in Indiana' Crittenden
        the print BLOCK LIST form is, I suspect, analagous to something like map BLOCK list, where the BLOCK is converted into an anonymous sub which returns the value of the last expression in the block. These are syntactically different from naked BLOCKs. You can also get this behaviour with subroutine prototypes:
        sub MySub (&\@) { ... } MySub { # do something, return a value } @list;
           MeowChow                                   
                       s aamecha.s a..a\u$&owag.print
        The "indirect object" uses a block for its syntax, and is a different rule than a general block in the middle of an expression.
Re (tilly) 1: {} vs do{}
by tilly (Archbishop) on Jul 04, 2001 at 08:40 UTC
    Let me give a few sample cases where you want one and not the other.

    If you want to use the return value, then you want to use do:

    # Trick for generating a symbol to use as, for instance, # a filehandle... my $fh = do {local *FH};
    If you want to use loop control, then you have to use a bare block. merlyn gives some ideas at RE: My favorite looping mechanism in Perl is: about why you might want to do that.

    If you want to put several statements where syntactically only one is supposed to go, you would want do. That might look like this:

    do {print "Hello"; print " World\n";} for 1..10;
    Note that I don't feel the need for this use of do. So I will follow up with a use for bare blocks that I feel is equally useless. Suppose you don't like semi-colons. Well help is at hand!
    {print "Hello"} {print " World\n"} # etc
    Does that clarify the similarities and differences?
Re: {} vs do{}
by japhy (Canon) on Jul 04, 2001 at 08:42 UTC
    The basic thing is: a BLOCK is not an EXPR(ession), but do BLOCK allows you to treat a BLOCK as an EXPR.

    japhy -- Perl and Regex Hacker
      I see. In all the time I've been using Perl, I've sometimes run into times when I tried to use a block in an expression and it doesn't work. Putting do in front makes it work.

      Thanks for all the replies, everyone, this holiday.

      —John

        Just keep in mind the important caveat that:
        do { BLOCK } while ( COND );
        is NOT equivalent to:
        while ( COND ) { BLOCK }
        In the first case, the code in BLOCK is executed once before checking the condition. This goes for until as well. However:
        do { BLOCK } for ( LIST );
        is equivalent to:
        for ( LIST ) { BLOCK }
           MeowChow                                   
                       s aamecha.s a..a\u$&owag.print
Re: {} vs do{}
by Zaxo (Archbishop) on Jul 04, 2001 at 08:53 UTC

    You can use a naked block anywhere. One good reason to is to limit the scope of lexical variables:

    { # file is not world readable! my $password = 'my_secret'; sub my_privy { # do private things } }
    do BLOCK; returns the value of the last expression evaluated, so assignment becomes possible:

    my $val = do { # valuable stuff };

    When used with modifier while or until the do block is evaluated once before the condition is tested.

    After Compline,
    Zaxo

      The two most common methods of these that I use are as follows:
      {} :
      I use this to slurp files ie:
      { local $/ = undef; $data = <FH>; }
      The anonymous block allows me to change the record separator locally and slurp the file in one go without impacting the rest of my program. This is simply another example of scoping as with the previous post. Note you'll have to open the file first etc....
      do:
      I use do mainly in two cases. To dynamically load Perl modules in my servers and to implement switch style code (see perl.com for examples). ie.. assuming $_ has our test variable
      . . . . . . . /^test$/ && do { } . . . . . . .
      That was a bit cryptic (sorry) but the explanation on perl.com is much better than what I could write so please look there. Hope that gives you an idea of applications as well as differences!