Shlomi Fish <shlo...@shlomifish.org> writes: > Hi Lee, > > On Sun, 23 Jun 2013 04:43:58 +0200 > lee <l...@yun.yagibdah.de> wrote: > >> James Alton <jamesalton...@gmail.com> writes: >> >> > lee, >> > >> > You have a post statement if and then a code block. You can only use one of >> > two forms: >> > >> > print "test" if $color eq "blue"; #no parenthesis required >> > if($color eq "blue"){print "test";} >> >> And I can't have 'last if $color eq "blue" print "test\n";'? That would >> be something quite natural and a logical thing to do ... > > Do you want something like: > > if ($color eq "blue") > { > last; > } > else > { > print "test\n"; > } > > Because I cannot parse the meaning of your other statement.
It would be like: if($color eq "blue") { print "test\n"; last; } An 'if' is an 'if', and when putting 'last' in front of it changes it to something else, why isn't there a keyword for it like 'lastif'? >> > As far as last, http://perldoc.perl.org/functions/last.html > [...] >> > What they're saying here is that it breaks out of a loop. Its not like a >> > return where it breaks out of a subroutine, it just continues beyond the >> > loop. >> >> Yes, I looked at that and found it rather confusing. Now I guess it >> breaks out of the current (innermost) loop unless a label is being used >> which would allow to break out of whatever loop the label refers to, >> like: >> >> >> BREAK: while($loop_1) { >> # do something with $color and $loop_2 >> while($loop_2) { >> last BREAK if $color eq "blue"; >> print "not blue\n"; >> # do something with $color and $loop_2 >> } >> } >> print "broken\n"; >> > > Yes, Perl Best Practices recommends to always use a label with "last", "redo" > or "next" to avoid problems where you add or remove more inner loops. I agree > with it here: > > http://perl-begin.org/tutorials/bad-elements/#flow-stmts-without-labels It seems to me that adding another loop can break the code no matter whether you use labels or not. Consider above example and let's add another loop, which then looks like this: BREAK: while($loop_1) { # do something with $color and $loop_2 while($loop_2) { # added some stuff here while($foo) { # added some more stuff here last BREAK if $color eq "blue"; print "not blue\n"; # do something about $foo } # do something with $color and $loop_2 } } print "broken\n"; Assume you overlooked the label. Now after a while of programming or maybe even days later you find that your code doesn't work as expected. You come back to it and either you still overlook the label and have trouble figuring out what's going on, or you will be asking yourself what you actually wanted to do. The label only makes sure that the script will break out of a particular loop, and that may be the one you want it to break out of or not. The assumption that "later on, one may modify the code to insert a loop in between the innermost loop and the flow control statement, which will break the code"[1] can be true or not, no matter whether labels have been used or not. When we were still programming in BASIC, the using of 'goto' statements was considered very bad style. The using of labels in perl like this doesn't seem to be any different. Sure it can be useful, but if I had to use a label like this, I'd feel that I should put big fat warnings about it into a comment /because/ it is more likely to break the code when changes are made than not using a label like this is. [1]: http://perl-begin.org/tutorials/bad-elements/#flow-stmts-without-labels > Yesterday, I introduced a bug or two in my C code (which were luckily caught > by > the tests) because I removed a loop and as result a few C "continue" > statements > (which is equivalent to Perl 5’s "next") terminated the more previously outer > loop. It is possible that the C compilers of > http://en.wikipedia.org/wiki/GNU_Compiler_Collection and > http://en.wikipedia.org/wiki/Clang have extensions for doing that similar to > what Perl has, but I couldn't find them yet. Spaghetti code in C? ;) Maybe I'm overlooking something; do you have a good example where using a label prevents you from breaking the code? >> >> The really confusing part is/was what the 'last' statement actually does >> when used in conjunction with an 'if'. Apparently it re-defines the >> meaning of 'if' --- or there are multiple versions of 'if' in perl: > > No, it does not. It does: while($test) { if($foo) { print $bar; last; } else { print $test; } } That would work, and while($test) { last if($foo) { print $bar; } else { print $test; } } doesn't work. (The 'else' branch is redundant and may be wanted for better readability.) Prefixing 'last' to an 'if' clearly modifies the 'if' to something that cannot do what an 'if' does. Otherwise, the second example would work as expected. >> One >> version is the "usual" one like 'if(condition) { foo; } else { bar; }'. >> The other one is some sort of appendix which is logically prepended >> to the statement and, unfortunately, lacks the ability to do something >> besides the statement it is appended to. Maybe '$color eq "blue" ? >> print "test" : print "red\n" if $color eq "red";' ... >> > > Actually, it is appended instead of prefixed, and you can do any single > statement inside that, like: > > $x = $y if COND(); > > print "Hello\n" if COND(); > > etc. That's because it's logically prefixed though it's syntactically appended. It's like writing instructions for making fried potatoes, and only at the end of the instructions you tell the reader that they were supposed to skin the potatoes and to cut them into slices before they started frying them ;) > See http://perldoc.perl.org/perlsyn.html#Statement-Modifiers Hm, 'open(FOO) ? () : die "Can't open $FOO: $!";' is kinda cute :) > Also, please don't use the ternary conditional operator for side-effects, see: > > http://perl-begin.org/tutorials/bad-elements/#ternary_operator_instead_of_if_else What is considered as 'side effects'? Should one use it without effects? >> So how about: >> >> >> { >> print "123\n"; >> print "456\n"; >> } if $color eq "blue"; >> >> >> That doesn't compile, so this preappended 'if' is like implemented only >> half way in both directions :/ > > A trailing if applies only to one statement (by design). That's inconsistent design since statements in such brackets are effectively one statement ... > You can use: > > do { > print "123\n"; > print "456\n"; > } if $color eq "blue"; > > but in this case I believe a normal conditional with the condition at the > beginning would be preferable. I agree --- the whole concept of syntactically appending stuff that is logically prefixed seems a bit questionable. But then, nobody forces anyone to use it. -- "Object-oriented programming languages aren't completely convinced that you should be allowed to do anything with functions." http://www.joelonsoftware.com/items/2006/08/01.html -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/