Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Ternary operators

by geistberg (Novice)
on Dec 18, 2013 at 21:57 UTC ( #1067720=perlquestion: print w/ replies, xml ) Need Help??
geistberg has asked for the wisdom of the Perl Monks concerning the following question:

I am getting some unexpected results

code

#!/usr/bin/perl use warnings; use strict; use Data::Dumper; my ( $broken, $works ); my @list = qw( this that another ); for ( @list ) { $broken->{'this'} = $_ eq 'this' ? 1 : 0; $broken->{'that'} = $_ eq 'that' ? 1 : 0; $broken->{'another'} = $_ eq 'another' ? 1 : 0; } for ( @list ) { $works->{'this'} = 1 if $_ eq 'this'; $works->{'that'} = 1 if $_ eq 'that'; $works->{'another'} = 1 if $_ eq 'another'; } print Dumper $broken, $works;

result

perl example.pl $VAR1 = { 'another' => 1, 'that' => 0, 'this' => 0 }; $VAR2 = { 'another' => 1, 'that' => 1, 'this' => 1 };

I expected all the keys to be 1 in this case on the broken hash ref, but two of the 0's got through. I like the ternary operator but I think I made it angry, any thoughts?

Comment on Ternary operators
Select or Download Code
Re: Ternary operators (more ddumper)
by Anonymous Monk on Dec 18, 2013 at 22:08 UTC

    any thoughts?

    use more ddumper, like in the for loops, like ddumper $works at beginning and at end

Re: Ternary operators
by BrowserUk (Pope) on Dec 18, 2013 at 22:12 UTC

    With the ternary operator, the assignment always happens. It is only what is assigned that varies.

    Thus, on each iteration of the first for loop, all 3 hash values are assigned, but only one can be set to 1.

    In the second for loop, only one hash value is assigned during each pass.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Ternary operators
by roboticus (Canon) on Dec 18, 2013 at 22:13 UTC

    geistberg:

    No, you didn't make it angry.

    Let's take a look at the second loop first: Each time through the loop, you set a hash key to 1 if the current iteration of the loop ($_) matches the hash key. So in each iteration, you're setting only one key.

    In your first loop, however, you *always* set the value of each element: to 1 if the loop variable matches the hash key, and 0 otherwise, and the last iteration "wins".

    In short: the first loop sets each key to this or that. The second loop sets a key if there's a match.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: Ternary operators
by boftx (Chaplain) on Dec 18, 2013 at 22:15 UTC

    Step through your first loop by hand and see what is assigned each time through it. $broken->{this} is assigned "1" the first time, but is being assigned "0" and the second and third pass. Similarly for $broken->{that} and $broken->{another}.

    The end result is that only the results for the last pass is stored in the hash keys.

    It helps to remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: Ternary operators
by geistberg (Novice) on Dec 18, 2013 at 22:21 UTC

    You monks are most excellent, I feel a bit sheepish that I didn't brain that well. Thanks for the guidance.

      You monks are most excellent, I feel a bit sheepish that I didn't brain that well. Thanks for the guidance.

      :) we've all been there ... thats why the checklist was invented, pilots/doctors... all rely on checklists ... The Checklist Manifesto: How to Get Things Right

Re: Ternary operators
by ikegami (Pope) on Dec 20, 2013 at 16:36 UTC

    Note that it's called the conditional operator. It's merely one of a few ternary operators.

    If you wanted to use the conditional operator, it would look like the following:

    $broken->{this} = $_ eq 'this' ? 1 : $broken->{this}; $broken->{that} = $_ eq 'that' ? 1 : $broken->{that}; $broken->{another} = $_ eq 'another' ? 1 : $broken->{another};

    But that would be silly.

    You want

    $broken->{$_} = 1 for @list;

    or

    my @valid = qw( this that another ); $broken->{$_} = 0 for @valid; $broken->{$_} = 1 for @list;

    or

    my %valid = map { $_ => 1 } qw( this that another ); $broken->{$_} = 1 for grep $valid{$_}, @list;

    or

    my @valid = qw( this that another ); my %valid = map { $_ => 1 } @valid; $broken->{$_} = 0 for @valid; $broken->{$_} = 1 for grep $valid{$_}, @list;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1067720]
Approved by boftx
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (10)
As of 2014-09-23 22:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (241 votes), past polls