Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

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


#!/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;


perl $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?

Replies are listed 'Best First'.
Re: Ternary operators
by roboticus (Chancellor) on Dec 18, 2013 at 22:13 UTC


    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.


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

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 boftx (Deacon) 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 (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 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;


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


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


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

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1067720]
Approved by boftx
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2018-06-25 10:54 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (126 votes). Check out past polls.