Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Short form (ternary) if else

by gg48gg (Sexton)
on Feb 08, 2012 at 19:54 UTC ( #952567=perlquestion: print w/ replies, xml ) Need Help??
gg48gg has asked for the wisdom of the Perl Monks concerning the following question:

I don't think I understand the ternary ? : in perl. Can you help me understand why the below code is not working as expected?
(exists $vxdgs{$node}{$disk}) ? my $vxdg=$vxdgs{$node}{$disk} : my $vxdg="";
I am looking for a short form for...
if (exists $vxdgs{$node}{$disk}) { my $vxdg=$vxdgs{$node}{$disk}; } else { my $vxdg=""; }
Thank you.

Comment on Short form (ternary) if else
Select or Download Code
Re: Short form (ternary) if else
by SuicideJunkie (Priest) on Feb 08, 2012 at 19:57 UTC

    Perhaps you want to declare $vxdg outside the if, and only assign the value inside the if?

    my $vxdg = (exists $foo) ? $bar : 'baz';

Re: Short form (ternary) if else
by InfiniteSilence (Curate) on Feb 08, 2012 at 19:58 UTC

    perl -e 'my $n = 10; (1)? $n++ : $n--; print qq~This is $n\n~;'
    Prints:
    This is 11

    Celebrate Intellectual Diversity

Re: Short form (ternary) if else
by Riales (Hermit) on Feb 08, 2012 at 19:59 UTC
    I think what you're looking for is this:
    my $vxdg = exists $vxdg{$node}{$disk} ? $vxdg{$node}{$disk} : '';
    Also, in your if/else statement, if you declare $vxdg inside the if/else like you are doing, it goes out of scope by the time you get out of the if/else block.
      Yes, that works beautifully! Thank you! I realize the scope issue as well. So, what I understand is that ternary form is only for use after an assignment (=) operator? Is that correct?

        No, it doesn't have to be used in conjunction with assignment. Consider:

        printf("X is %s\n", defined $X ? $X : 'undefined');

        Or:

        sub get_name { # ... return wantarray ? ($firstname, $middlename, $lastname) : "$firstname $lastname"; }

        Yes and no... It is typically at it's most useful after an assignment, and it's use is that it generates a value, but that doesn't necessarily mean it needs to be used in an assignment. Others have given examples, but the essential thing to remember is that the ternary operator returns a value. if does not: It is a flow-control operator.

        So, where it does need to be used is where Perl would expect a value. Assignments are one common case of that.

Re: Short form (ternary) if else
by kcott (Abbot) on Feb 08, 2012 at 20:25 UTC

    The ternary operator exists in many programming languages and is often a stumbling block for many who encounter it for the first time. I'm sure I scratched my head over it too. Here's an example of usage:

    use strict; use warnings; my %hash = ( abc => 123 ); my $abc = exists $hash{abc} ? $hash{abc} : 0; my $xyz = exists $hash{xyz} ? $hash{xyz} : 0; print "ABC = $abc : XYZ = $xyz\n";

    This outputs:

    ABC = 123 : XYZ = 0

    Another thing you need to know is that variables declared with my are lexical. With your example code, this means the first $vxdgs only exists in the if block and the second $vxdgs only exists in the else block; furthermore, they are two completely separate variables with their own values.

    From your question, I believe the code you want is:

    my $vxdg = exists $vxdgs{$node}{$disk} ? $vxdgs{$node}{$disk} : "";

    -- Ken

      Thanks all! I realize the scope issue. So, what I understand is that ternary form is only for use after an assignment (=) operator? Is that correct?

        That's not correct. The ternary operator will generate some sort of value - what you do with that value is up to you. You could, for example, use it to create a boolean return value:

        return defined $result ? 1 : 0;

        You can also nest ternary operators. Say you wanted to compare two numbers and produce: 1 if the first number was bigger; 0 if they were the same; -1 if the second number was bigger:

        my $cmp = $x > $y ? 1 : $x == $y ? 0 : -1;

        -- Ken

Re: Short form (ternary) if else
by JavaFan (Canon) on Feb 08, 2012 at 22:38 UTC
    I am looking for a short form for...
    if (exists $vxdgs{$node}{$disk}) { my $vxdg=$vxdgs{$node}{$disk}; } else { my $vxdg=""; }
    Well, assuming %{$vxdgs}{$node} isn't a tied hash with side-effects, and $vxdgs{$node}{$disk} isn't a tied scalar with side-effects, your code is a noop. Both blocks assign something to a scalar variable, with both scalars going out of scope directly after the assignment.
Re: Short form (ternary) if else
by trwww (Priest) on Feb 09, 2012 at 04:09 UTC

    Why not just:

    my $vxdg = $vxdgs{$node}{$disk}

    ?

Re: Short form (ternary) if else
by Mandrake (Chaplain) on Feb 09, 2012 at 11:07 UTC
    Or probably
    my $vxdg = $vxdgs{$node}{$disk} || "";
    thanks

      Whenever I see this I usually see this right afterwards:

      if ( $vxdg != '' ) {

      Where they should probably be using:

      if ( $vxdg ) {

      Which would make the || "" in the assignment unnecessary.

      Yes, I understand sometimes zero and the empty string are distinct values from undef in many business rules, but I don't think that applies as aften as many coders believe.

      my $vxdg = $vxdgs{$node}{$disk} || "";
      This is short and sweet, but doesn't take into account a hash value of 0, which could be a valid value. So, if I had a hash value of 0, perl would evaluate it as false, and set the variable to blank.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2014-07-24 05:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (157 votes), past polls