Jürgen Exner said:
I disagree. This isn't one operation, it is two and they are quite
different. One assignment and one loop control jump.
Nobody ever claimed that they weren't.
And therefore it should look and feel like two operations, i.e. be
separated into two statements.
Perl has four operators which can be used to bind two different but
(in a certain context) related things together, '&& || and or
,'. Interpreted as general as it stand there, the sentence could as
easily apply to
if ($a == 1 && $b ne 'Huehnerdieb') { }
two different comparisons which are executed in sequence and thus,
should be two statements instead of this confusing conglomerate:
if ($a == 1) {
if ($b ne 'Huehnerdieb') { }
}
Consequently, this statement should be less general so that it is
applicable to assignment and loop-control operators but not to chained
comparisons.
You can easily see how confusing it is to munge them together: in just
this very thread there are already at least three different
interpretions of what the OP intended the code to do.
I'm not aware of any, but the OP stated quite plainly what he wanted
to do (as paraphrase: Why does it work with , but not with &&?) and
if at least three people existed who didn't understand a particular
text, presumably, because they jumped to conclusions about its
probable meaning before they finished reading it, that's not an argument
for or against anything: Whatever is said, someone will not listen and
misunderstand it.
It is just not worth this confusion. Consice code that is easy to
understand is way more important than shorting the code to the max.
Unless you are playing Perl golf, of course.
Nobody argued in favor of 'shorting code to the max' (a remarkably
nonsensical phrase .... shouldn't that be 'shorten it to the min'?).
Also, I am not convinced about your efficieny argument.
First and foremost, this was a statement of facts: The if-block makes
perl perform more operations than the 'block-free' variants. A
contrived example which demonstrates this (both at the 'op tree' level
and in terms of actual execution time, at least here):
-----------
use Benchmark;
my $x;
sub s1
{
if (rand(100) < 50) {
++$x;
return $x;
}
}
sub s2
{
++$x, return $x if rand(100) < 50;
}
timethese(-5, {
a => \&s1,
b => \&s2
});
-----------
For one nobody asked for the code to be as efficient as possible.
That's a different question.
And even if so I would still find it hard to believe that an if
statement is slower, because in both cases the same operations are
performed. Or actually in case of the statement modifier there is
even an additional and.
Well, you are wrong about that and I actually posted output of the
'Perl disassembler' that showed the difference. You can also get it
from the code above by using it as argument to
perl -MO=Concise,-exec,s1
perl -MO=Concise,-exec,s2
(first shows the first sub, 2nd the 2nd).
Not to mention that such micro-optimizations are rarely the right
approach. If a program is too slow then almost always a different
algorithm or a different overall approach is the answer.
Provided that a program is too slow, 'removing avoidable blocks' might
not be the best strategy in order to deal with that (although this is
by no means certain since 'wasting 1.5% at every opportunity for that'
can easily have a significant cumulative effect). But this is - at
best - a tangential aspect when technical properties of different ways
to do the same thing are discussed.
If you are really depending upon such micro-optimizations then
probably you should have chosen a different programming language,
probably one that allows lower-level control like C or assembler.
I really expect that people who write code are as concerned with using
their tools efficiently as people performing different tasks with
other tools, IOW, that the 'dominant programming problem' shouldn't be
"how to I get this to work at all" but "how can I make this work
sensibly".
This is, of course, not exactly a realistic proposition ...