Home > Archive > PERL Miscellaneous > July 2005 > true false ? : expression thingy
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
true false ? : expression thingy
|
|
|
| I'm not sure what this method is called, which is perhaps why I've had no
luck when searching around the web for info on it, but when you want a
1-line alternative to an if...else.. construct, you can use the following
syntax:
$ctr > 3 ? $text = "yes" : $text = "no";
that works fine, however, when I try this:
my $incsubs;
$line =~ /\ts/i ? $incsubs = 0 : $incsubs = 1;
it doesn't work.. well, $incsubs equals 1 regardless whereas it works in the
standard if...else.. construct.
I guess this is because the regular expression doesn't return true/false, or
sth like that.. is there a "trick" you can use to make this type of method
work with regexps?
Bigus
| |
| Anno Siegel 2005-07-28, 9:09 am |
| Bigus <someone@somewhere.com> wrote in comp.lang.perl.misc:
> I'm not sure what this method is called, which is perhaps why I've had no
> luck when searching around the web for info on it, but when you want a
> 1-line alternative to an if...else.. construct, you can use the following
> syntax:
>
> $ctr > 3 ? $text = "yes" : $text = "no";
>
> that works fine, however, when I try this:
>
> my $incsubs;
> $line =~ /\ts/i ? $incsubs = 0 : $incsubs = 1;
>
> it doesn't work.. well, $incsubs equals 1 regardless whereas it works in the
> standard if...else.. construct.
>
> I guess this is because the regular expression doesn't return true/false, or
> sth like that.. is there a "trick" you can use to make this type of method
> work with regexps?
Wrong diagnosis. A regex returns a boolean value in scalar context,
that part of your expression is quite all right.
Your problem is one of precedence. Perl parses your expression like
this:
( ( $line =~ /\ts/i) ? ( $incsubs = 0) : $incsubs) = 1;
So if you have a match, $incsubs is set to 0 and $incsubs is returned.
If you don't have a match, $incsubs is not set to 0, but returned as is.
In either case what is returned is $incsubs, and 1 is assigned to it
unconditionally. Hence the result you see.
Generally, the "?:" construct (sometimes called "ternary conditional",
btw) should not be used for operations that have a side effect, like
the assignments you are doing. Use a normal if/else for that, even if
it's a bit longer.
Using "?:", your conditional assignment can be written:
my $incsubs = $line =~ /\ts/i ? 0 : 1;
Now the assignment is outside the "?:". But now it becomes apparent
that this is (almost) equivalent to
my $incsubs = $line !~ /\ts/i;
which is what I would use.
Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
| |
|
| "Anno Siegel" <anno4000@lublin.zrz.tu-berlin.de> wrote in message
news:dcaenn$d40$1@mamenchi.zrz.TU-Berlin.DE...
> Bigus <someone@somewhere.com> wrote in comp.lang.perl.misc:
[..]>> my $incsubs;
[..][color=darkred]
> Your problem is one of precedence. Perl parses your expression like
> this:
>
> ( ( $line =~ /\ts/i) ? ( $incsubs = 0) : $incsubs) = 1;
>
> So if you have a match, $incsubs is set to 0 and $incsubs is returned.
> If you don't have a match, $incsubs is not set to 0, but returned as is.
> In either case what is returned is $incsubs, and 1 is assigned to it
> unconditionally. Hence the result you see.
Ahhh, so this would work:
my $incsubs;
$line =~ /\ts/i ? ($incsubs = 0) : ($incsubs = 1);
> Generally, the "?:" construct (sometimes called "ternary conditional",
> btw) should not be used for operations that have a side effect, like
> the assignments you are doing. Use a normal if/else for that, even if
> it's a bit longer.
>
> Using "?:", your conditional assignment can be written:
>
> my $incsubs = $line =~ /\ts/i ? 0 : 1;
>
> Now the assignment is outside the "?:". But now it becomes apparent
> that this is (almost) equivalent to
>
> my $incsubs = $line !~ /\ts/i;
OK, that sounds good. I 'll use that in this case. The previous syntax would
be useful in situations where I want to make a non boolean assigment
resulting from a regexp match.
Thanks
Bigus
| |
| Ian Wilson 2005-07-29, 9:04 am |
| Bigus wrote:
> when you want a
> 1-line alternative to an if...else.. construct,
Whilst I quite like
$this = condition ? "foo" : "bar";
What's so horrible about
if (condition) {$this="foo";} else {$this="bar"}
which I find quite readable?
| |
| Juha Laiho 2005-07-29, 9:04 am |
| "Bigus" <someone@somewhere.com> said:
>"Anno Siegel" <anno4000@lublin.zrz.tu-berlin.de> wrote in message
>news:dcaenn$d40$1@mamenchi.zrz.TU-Berlin.DE...
>my $incsubs;
>$line =~ /\ts/i ? ($incsubs = 0) : ($incsubs = 1);
>
>
>OK, that sounds good. I 'll use that in this case. The previous syntax would
>be useful in situations where I want to make a non boolean assigment
>resulting from a regexp match.
Hmm.. somewhat yes; a non-boolean assignment based on whether a regexp
did match or not. But then, if you assign constant values, you're after
all assigning "a form of boolean" (that is, after the operation the
variable will have one of two possible values, and later on something
will depend on which of the two values was assigned).
So, cases where you really have a use for this shorthand are not that
common (esp. given the overall syntactic flexibility of perl), and
when you finally have a case complex enough to warrant this, it might
be at the same time complex enough to warrant a full-blown conditional
construct.
--
Wolf a.k.a. Juha Laiho Espoo, Finland
(GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
"...cancel my subscription to the resurrection!" (Jim Morrison)
| |
| Paul Lalli 2005-07-29, 9:04 am |
| Ian Wilson wrote:
> Bigus wrote:
>
> Whilst I quite like
> $this = condition ? "foo" : "bar";
>
> What's so horrible about
> if (condition) {$this="foo";} else {$this="bar"}
> which I find quite readable?
For one thing, it takes even longer if you are properly scoping your
variables (and this is the first instance of the variable:
my $this = condition() ? 'foo' : 'bar';
# vs...
my $this;
if (condition()) { $this = 'foo' } else { $this = 'bar' }
It's not so much a matter of readabilty, it's a matter of conciseness.
For me anyway.
The former tells you straight out that $this is going to be one thing
or another based on condition(). The latter only tells you that
something or something else will happen based on condition(), and you
have to visually scan the remainder of the block to know that the two
options are the possible values of a single variable.
Paul Lalli
| |
| Sven-Thorsten Fahrbach 2005-07-29, 9:04 am |
| On Fri, 29 Jul 2005 10:04:54 +0000 (UTC)
Ian Wilson <scobloke2@infotop.co.uk> wrote:
> Bigus wrote:
>
> Whilst I quite like
> $this = condition ? "foo" : "bar";
>
> What's so horrible about
> if (condition) {$this="foo";} else {$this="bar"}
> which I find quite readable?
>
The ternary operator looks wonderfully g y ;-). But I agree with you, you should use if ... else for more sophisticated conditionals, for your own sake and your co-workers'.
| |
| Tad McClellan 2005-07-29, 9:04 am |
| Ian Wilson <scobloke2@infotop.co.uk> wrote:
> Bigus wrote:
>
> Whilst I quite like
> $this = condition ? "foo" : "bar";
>
> What's so horrible about
"horrible" is prejudicial, putting the question in a more reasoned manner:
Why prefer it over
> if (condition) {$this="foo";} else {$this="bar"}
As with most style issues, the choice should be based on clearly
communicating the code's intent.
A commonly accepted style-choice here is to use the 1st for a
conditional _value_ and the 2nd for conditional flow control.
So the 1st would be preferred _here_, because ?: (should) always means
"select a value", while you have to analyse the 2nd only to come
to what would be a foregone conclusion if the 1st had been used instead.
--
Tad McClellan SGML consulting
tadmc@augustmail.com Perl programming
Fort Worth, Texas
| |
| Sven-Thorsten Fahrbach 2005-07-29, 5:03 pm |
| On Fri, 29 Jul 2005 08:42:32 -0500
Tad McClellan <tadmc@augustmail.com> wrote:
> As with most style issues, the choice should be based on clearly
> communicating the code's intent.
>
> A commonly accepted style-choice here is to use the 1st for a
> conditional _value_ and the 2nd for conditional flow control.
>
> So the 1st would be preferred _here_, because ?: (should) always means
> "select a value", while you have to analyse the 2nd only to come
> to what would be a foregone conclusion if the 1st had been used instead.
Good point. I think a good illustration is the following code:
printf ("\$foo is %s.\n", $foo ? "true" : "false");
This is (in my opinion) even more concise than:
if ($foo) {
print "\$foo is true.\n";
}
else {
print "\$foo is false.\n";
}
You shouldn't use the ternary operator if you're dealing with something like:
if (($condition1) && ($value1 == $value2) && (! $condition2)) {
# long piece of code
}
else {
# another long piece of code
}
This may sound trivial though, I think one should rely on common sense as when to use the two conditionals.
| |
| xhoster@gmail.com 2005-07-29, 5:03 pm |
| Ian Wilson <scobloke2@infotop.co.uk> wrote:
> Bigus wrote:
>
> Whilst I quite like
> $this = condition ? "foo" : "bar";
>
> What's so horrible about
> if (condition) {$this="foo";} else {$this="bar"}
> which I find quite readable?
Where do you put the "my"?
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
| |
| John W. Kennedy 2005-07-29, 10:01 pm |
| Ian Wilson wrote:
> Bigus wrote:
>
>
>
> Whilst I quite like
> $this = condition ? "foo" : "bar";
>
> What's so horrible about
> if (condition) {$this="foo";} else {$this="bar"}
> which I find quite readable?
For one thing, you can't use it as an alternative to:
my $this = condition ? "foo" : "bar";
And it is more economical in a case like:
$x[$i + $j - 1] = condition ? "foo" : "bar";
--
John W. Kennedy
"I want everybody to be smart. As smart as they can be. A world of
ignorant people is too dangerous to live in."
-- Garson Kanin. "Born Yesterday"
| |
| John W. Krahn 2005-07-30, 4:00 am |
| John W. Kennedy wrote:
> Ian Wilson wrote:
>
> For one thing, you can't use it as an alternative to:
>
> my $this = condition ? "foo" : "bar";
>
> And it is more economical in a case like:
>
> $x[$i + $j - 1] = condition ? "foo" : "bar";
And don't forget you can use it as an lvalue as in:
( condition ? $foo : $bar ) = $this;
Or:
push @{ condition ? \@foo : \@bar }, $this;
John
--
use Perl;
program
fulfillment
| |
| Abigail 2005-07-30, 5:00 pm |
| John W. Kennedy (jwkenne@attglobal.net) wrote on MMMMCCCLI September
MCMXCIII in <URL:news:71CGe.2716$7Q1.1993@fe09.lga>:
!! Ian Wilson wrote:
!! >
!! > What's so horrible about
!! > if (condition) {$this="foo";} else {$this="bar"}
!! > which I find quite readable?
!!
!! For one thing, you can't use it as an alternative to:
!!
!! my $this = condition ? "foo" : "bar";
my $this = do {if (condition) {"foo"} else {"bar"}};
HTH. HAND.
Abigail
--
perl5.004 -wMMath::BigInt -e'$^V=Math::BigInt->new(qq]$^F$^W783$[$%9889$^F47]
.. qq]$|88768$^W596577669$%$^W5$^F3364$[$^W
$^F$|838747$[8889739$%$|$^F673$%$^W]
..qq]98$^F76777$=56]);$^U=substr($]=>$|=>5)*(q.25..($^W=@^V))=>do{print+chr$^V
%$^U;$^V/=$^U}while$^V!=$^W'
| |
| Abigail 2005-07-30, 5:00 pm |
| John W. Krahn (someone@example.com) wrote on MMMMCCCLI September MCMXCIII
in <URL:news:oTEGe.162969$9A2.73587@edtnps89>:
__ John W. Kennedy wrote:
__ > Ian Wilson wrote:
__ >> Bigus wrote:
__ >>
__ >>> when you want a
__ >>> 1-line alternative to an if...else.. construct,
__ >>
__ >>
__ >> Whilst I quite like
__ >> $this = condition ? "foo" : "bar";
__ >>
__ >> What's so horrible about
__ >> if (condition) {$this="foo";} else {$this="bar"}
__ >> which I find quite readable?
__ >
__ > For one thing, you can't use it as an alternative to:
__ >
__ > my $this = condition ? "foo" : "bar";
__ >
__ > And it is more economical in a case like:
__ >
__ > $x[$i + $j - 1] = condition ? "foo" : "bar";
__
__ And don't forget you can use it as an lvalue as in:
__
__ ( condition ? $foo : $bar ) = $this;
${;do {if (condition) {\$foo} else {\$bar}}} = $this;
__ Or:
__
__ push @{ condition ? \@foo : \@bar }, $this;
push @{;do {if (condition) {\@foo} else {\@bar}}}, $this;
It ain't pretty, but you can replace ?: with 'if'.
Abigail
--
END {print "Hacker\n"}
CHECK {print "another "}
BEGIN {print "Just " }
INIT {print "Perl " }
|
|
|
|
|