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 | [reply] [d/l] |
|
|
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
| [reply] [d/l] [select] |
|
|
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 | [reply] [d/l] [select] |
|
|
The "indirect object" uses a block for its syntax, and is a different rule than a general block in the middle of an expression.
| [reply] |
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? | [reply] [d/l] [select] |
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 | [reply] |
|
|
| [reply] [d/l] |
|
|
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 | [reply] [d/l] [select] |
|
|
Re: {} vs do{}
by Zaxo (Archbishop) on Jul 04, 2001 at 08:53 UTC
|
{
# 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 | [reply] [d/l] [select] |
|
|
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! | [reply] [d/l] [select] |