Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Refactoring: dumb or witty use of ternary operator?

by PetaMem (Priest)
on Jun 21, 2004 at 21:47 UTC ( #368559=perlquestion: print w/ replies, xml ) Need Help??
PetaMem has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

I'm refactoring code of a former colleague, who sometimes was brilliant implementing things, and sometimes - well...

I stumbled across a module where he uses tons of these constructs:

$outhash{$str} ? ($outhash{$str}++) : ($outhash{$str} = 1);
Standalone - not as right value of anything. Looking at the context (no context for the hash), I think the whole construct is equivalent to:
$outhash{$str}++;
Or am I overseeing some "important" side effect? Thanks for sharing your insight.

Bye
 PetaMem
    All Perl:   MT, NLP, NLU

Comment on Refactoring: dumb or witty use of ternary operator?
Select or Download Code
Re: Refactoring: dumb or witty use of ternary operator?
by borisz (Canon) on Jun 21, 2004 at 21:52 UTC
    You are right. Its all the same as $outhash{$str}++;
    Boris
Re: Refactoring: dumb or witty use of ternary operator?
by herveus (Parson) on Jun 21, 2004 at 22:05 UTC
    Howdy!

    Interesting... Using perl 5.6.1 on solaris:

    #!/home/mhough/perl/bin/perl use strict; use warnings; use Data::Dumper; my %outhash = (abc => 1, def => undef); my %outhash2 = %outhash1 print Dumper(\%outhash, \%outhash2); foreach my $str (qw/abc def ghi/) { $outhash{$str}? ($outhash{$str}++) : ($outhash{$str} = 1); $outhash2{$str}++; } print Dumper(\%outhash, \%outhash2);
    yields:
    $VAR1 = {
              'abc' => 1,
              'def' => undef
            };
    $VAR2 = {
              'abc' => 1,
              'def' => undef
            };
    $VAR1 = {
              'abc' => 2,
              'def' => 1,
              'ghi' => 1
            };
    $VAR2 = {
              'abc' => 2,
              'def' => '1',
              'ghi' => '1'
            };
    

    Note the subtle difference between key 'def' in the two cases. It would appear that autoincrement on an undef does the magical string autoincrement, leading to a string value of '1', while the code FatVamp offers sets a numeric value of 1.

    What does it mean? I don't know, but the two forms do have ever so slightly different results whose difference probably doesn't matter.

    yours,
    Michael
      And if one were concerned, one could do
      $outhash{$str} += 1;
      to ensure numeric context.

      We're not really tightening our belts, it just feels that way because we're getting fatter.

      If that matters to someone, they might consider something like:

      ++( $outhash{$str} ||= 0 );

      - tye        

Re: Refactoring: dumb or witty use of ternary operator?
by cLive ;-) (Parson) on Jun 22, 2004 at 04:32 UTC

    Or am I overseeing some "important" side effect?

    Probably a warnings freak like me :) If the the value of $outhash{$str} is undefined, you'll get a warning about using an undefined value. update - you won't but I bet your colleague assumed the same thing that I did :)

    My guess is that the keys aren't known until the script is run, and that's your colleague's way of getting rid of the warnings. A perfectly valid way too. They are making you explicitly aware of the fact that $outhash{$str} may be undefined when you try to increment it.

    This would work equally well:

    $outhash{$str}||=0; $outhash{$str}++;

    .02

    cLive ;-)

      If the the value of $outhash{$str} is undefined, you'll get a warning about using an undefined value.

      This was my first thought too, but then the plain mentioning of $outhash{$str} in the ternary operator test section should do also - shouldn't it?

      Bye
       PetaMem
          All Perl:   MT, NLP, NLU

        Neither methods generate a warning for me, using perl 5.8.4.

        $ perl -wle '$outhash{$ARGV[0]}++; print $outhash{$ARGV[0]}' foo 1 $ perl -wle '$outhash{$ARGV[0]} ? ($outhash{$ARGV[0]}++) : ($outhash{$ARGV[0]} = 1); print $outhash{$ARGV[0]}' foo 1 $
        Try this:
        #!/usr/bin/perl use strict; use warnings; my $x; $x = $x+1; print $x;
        I get:
        Use of uninitialized value in addition (+) at tmp.pl line 6.
        Then try:
        #!/usr/bin/perl use strict; use warnings; my $x; $x = $x ? $x+1 : 1; print $x;
        to see the difference...

        cLive ;-)

      If the the value of $outhash{$str} is undefined, you'll get a warning about using an undefined value.
      Are you sure about that? Can you show code giving the warning? If you can construct code that generates a warning when ++ is applied to an undefined value, make sure to report it as a bug, because that's not supposed to happen.
      This would work equally well:
      $outhash {$str} ||= 0; $outhash {$str} ++;
      Yeah, but why bother? From the documentation about auto-increment and auto-decrement:
      "undef" is always treated as numeric, and in particular is changed to 0 before incrementing (so that a post-increment of an undef value will return 0 rather than "undef").

      Abigail

        "Are you sure about that?".

        No, obviously, but my guess is that his colleague made the same assumption that I did :)

        cLive ;-)

      If that were a check for an undef value, it should have used the defined() test which is instructive to us when trying to understand the code.
Re: Refactoring: dumb or witty use of ternary operator?
by Jasper (Chaplain) on Jun 22, 2004 at 08:13 UTC
    In work somewhere we had:
    $foo = defined $foo ? $foo : undef
    You can't make this **** up!
Re: Refactoring: dumb or witty use of ternary operator?
by Abigail-II (Bishop) on Jun 22, 2004 at 10:10 UTC
    I think the only possible side effects here would be if %outhash or $outhash {$str} is tied, or if $outhash {$str} is an object with an overloaded ++ operator. Or if the program has overloaded integers (for instance, if use Math::BigInt ':constant' is in use).

    Abigail

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (14)
As of 2014-09-16 14:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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











    Results (29 votes), past polls