Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
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 pondering the Monastery: (12)
As of 2015-07-07 12:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (88 votes), past polls