Re: Any difference in conditionals?
by davido (Cardinal) on Apr 27, 2004 at 01:43 UTC
|
You might be interested in how this parses with B::Deparse.
First, the test code:
if ($x1) {
if ($x2) {
print "here\n";
}
}
if ( $x1 && $x2 ) {
print "here\n";
}
And now the output under 'deparse,-x9' (the greatest degree of deparsing):
C:\Perl\scripts>perl -MO=Deparse,-x9 mytest.pl
$x1 and do {
$x2 and do {
print "here\n"
}
};
$x1 and $x2 and do {
print "here\n"
};
mytest.pl syntax OK
Surprised? :)
They are different, but also similar in more ways than you might initially guess. The biggest difference is nesting.
| [reply] [d/l] [select] |
Re: Any difference in conditionals?
by Zaxo (Archbishop) on Apr 27, 2004 at 01:36 UTC
|
As they stand, they are logically equivalent.
Your type1 is noisier, but more flexible. If steps may be added for other logical combinations, it will be easier to modify. Readibility declines rapidly with that.
I would prefer type2 for anything that is expected to be stable. It can be reduced further by modifier syntax,
print 'here', $/ if $x1 && $x2;
or logical operators,
$x1 && $x2 && print 'here', $/;
which some regard as unreadable, but I like for the lack of noise. The modifier syntax suffers from the need to squeeze everything in the conditional into a single Perl expression.
| [reply] [d/l] [select] |
|
|
Um, your logical operator expression also squeezes the conditional into a single Perl expression. It just happens to use the same operator inside as the conditional.
| [reply] |
Re: Any difference in conditionals?
by jeffa (Bishop) on Apr 27, 2004 at 06:19 UTC
|
# conditional type1
if ($x1) {
warn "x1 was true\n";
if ($x2) {
warn "x2 was true\n";
print "here\n";
}
}
# conditional type2
if ($x1 && $x2) {
warn "well, they were both true ... still don't see the bug\n";
print "here\n";
}
Now, the examples are very trivial, but i really have picked a more verbose style over
another just so i could debug easier -- verbose can still be terse with Perl, though. ;)
| [reply] [d/l] |
|
|
This thought got me thinking...
if($x1 && (warn '$x1 OK... ') && $x2) {
print "here\n";
}
... works like one might want it to work :)
So _technically_ even this method allows for debugging.
--Brock | [reply] [d/l] |
Re: Any difference in conditionals?
by pbeckingham (Parson) on Apr 27, 2004 at 02:16 UTC
|
when I use perl -MO=Concise test.pl, I get:
if ($x1)
{
if ($x2)
{
print "here\n";
}
}
a <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 5 if.pl:1) v ->3
- <1> null vK/1 ->a
4 <|> and(other->5) vK/1 ->a
- <1> ex-rv2sv sK/1 ->4
3 <#> gvsv[*x1] s ->4
- <@> scope vK ->-
- <0> ex-nextstate v ->5
- <1> null vK/1 ->-
6 <|> and(other->7) vK/1 ->a
- <1> ex-rv2sv sK/1 ->6
5 <#> gvsv[*x2] s ->6
- <@> scope vK ->-
- <0> ex-nextstate v ->7
9 <@> print vK ->a
7 <0> pushmark s ->8
8 <$> const[PV "here\n"] s ->9
And then the more concise:
if ($x1 && $x2)
{
print "here\n";
}
a <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 3 if.pl:1) v ->3
- <1> null vK/1 ->a
6 <|> and(other->7) vK/1 ->a
- <1> null sK/1 ->6
4 <|> and(other->5) sK/1 ->6
- <1> ex-rv2sv sK/1 ->4
3 <#> gvsv[*x1] s ->4
- <1> ex-rv2sv sK/1 ->-
5 <#> gvsv[*x2] s ->6
- <@> scope vK ->-
- <0> ex-nextstate v ->7
9 <@> print vK ->a
7 <0> pushmark s ->8
8 <$> const[PV "here\n"] s ->9
...and if I have ignored the optimized-out ops properly, they are identical.
| [reply] [d/l] [select] |
Re: Any difference in conditionals?
by pboin (Deacon) on Apr 27, 2004 at 16:15 UTC
|
The way you wrote it, no (real) difference, 'cause you're just accessing the values in $x1 and $x2. If, on the other hand, you were doing something like incrementing one of them, they are *very* different.
The logical AND is lazy. By that I mean when perl is doing the test, if the first half evaluates to false, the second half doesn't get evaluated at all. It can get you into trouble if you don't know to expect it.
In method #2 below, the $x1 gets incrmented and $x2 doesn't.
#!/usr/bin/perl
use strict;
my $x1 = 1;
my $x2 = 1;
print "\$x1 starts as $x1 and \$x2 starts as $x2.\n";
# method 1
if ($x1++) {
if ($x2++) {
print "We incremented \$x1 to $x1 and \$x2 to $x2.\n";
}
}
undef $x1;
undef $x2;
print "Undefine them both...\n";
#method 2
if ($x1++ && $x2++){
print "Shouldn't ever get here!\n";
}
print "Now, we incremented \$x1 to '$x1' and \$x2 is still '$x2'.\n";
| [reply] [d/l] |
|
|
Your tests aren't equivalent. In method 1, both variables start out as 1. In method 2, both variables start undefined. If you start with the same state in both tests, the results will be identical, both for the 'start as 1' case and the 'start undefined' case.
| [reply] |
Re: Any difference in conditionals?
by kragen (Sexton) on Apr 27, 2004 at 16:09 UTC
|
The first one is harder to read. I choose the first one never, the second one always. (Sometimes more complex logic justifies nested conditionals.) | [reply] |
|
|
I prefer print "Here\n" if $x1 and $x2; for most circumstances.
| [reply] [d/l] |