Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Refactoring: dumb or witty use of ternary operator?

by PetaMem (Priest)
on Jun 21, 2004 at 21:47 UTC ( [id://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

Replies are listed 'Best First'.
Re: Refactoring: dumb or witty use of ternary operator?
by herveus (Prior) 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

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

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

      - tye        

      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.
Re: Refactoring: dumb or witty use of ternary operator?
by cLive ;-) (Prior) 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.
      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.
      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

        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 ;-)

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

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!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
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?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (3)
As of 2024-04-20 09:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found