Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

strange output from conditional operator

by december (Pilgrim)
on May 15, 2009 at 11:38 UTC ( #764248=perlquestion: print w/replies, xml ) Need Help??

december has asked for the wisdom of the Perl Monks concerning the following question:

Hello, fellow monks;

I've gotten some strange results for some code I'm writing. I've made a short test case which I hope somebody can explain the results of to me.

use strict; use warnings; my @arr = ('one', 'apple', 'two', 'apple', 'three'); my $var; my $matches = 0; foreach my $el (@arr) { (defined($var) ? $var .= 'y' : $var .= 'n') if $el eq 'apple'; $matches++ if $el eq 'apple'; } print "$var\n"; print "$matches\n"; $var = 'x'; $matches = 0; foreach my $el (@arr) { (defined($var) ? $var .= 'y' : $var .= 'n') if $el eq 'apple'; $matches++ if $el eq 'apple'; } print "$var\n"; print "$matches\n";
nyn 2 xynyn 2

Nevermind rewriting the code bringing the assignment/appending operator outside of the comparison. I would like to know why this specific code prints such strange results (I would expect 'ny' for the former and 'xyy' for the latter fragment).

I understand '=' and '.=' can return something, but I don't understand how it gets assigned back to $var or why the non-matching part of the conditional gets executed.

What am I missing here?

Replies are listed 'Best First'.
Re: strange output from conditional operator
by moritz (Cardinal) on May 15, 2009 at 11:43 UTC

      Yes that works I knew it does but I was wondering why doing it this way caused such strange output...

      I've given thought to operator precedence, but I figured things wouldn't align up and I'd get a warning or error.

      So how would this get parsed? Something like the following I presume:

      (defined($var) ? $var) .= ('y' : $var .= 'n') if $el eq 'apple';

      Thanks for the explanation, operator precedence makes a lot more sense now. I'm just surprised things lined up well enough not to cause any warnings or syntax errors.

        The thread I've linked to above has an example both for how something very similar gets parsed, and how to find out how it's parsed. Did you not read it?
        (defined($var) ? $var) .= ('y' : $var .= 'n') if $el eq 'apple';
        No, because there can be no ? without an accompanying :. Thus, the ‘middle’ assignment is parsed as you like (since the tokeniser hasn't seen a : yet, hence knows that it's still inside the conditional), but the ‘last’ one isn't (since the tokeniser believes it's done with the conditional after finding the second occurrence of $var):
        (defined($var) ? $var .= 'y' : $var) .= 'n'

        (Of course, the statement about every ? requiring an accompanying : is a lie, as regular expressions show; but you know what I mean. :-) )

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://764248]
Approved by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2022-01-19 15:08 GMT
Find Nodes?
    Voting Booth?
    In 2022, my preferred method to securely store passwords is:

    Results (55 votes). Check out past polls.