Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Possible useless use of map

by Anonymous Monk
on Mar 18, 2010 at 10:13 UTC ( [id://829366]=note: print w/replies, xml ) Need Help??


in reply to Possible useless use of map

Could this bug have been picked up by some sibling of use warnings ?

Based on what? Lets see

  • you're using map in void context, but that has been silenced since 5.9.0
  • you're treating $hr as a hashref, but you're discarding the value, hmmm, lets check
    $ perl -Mstrict -Mwarnings -le " my $hr; $hr->{stuff}" Useless use of hash element in void context at -e line 1. $ perl -Mstrict -Mwarnings -le " my $hr; map { $hr->{stuff} } 1" $ perl -Mstrict -Mwarnings -le " my $hr; $hr->{stuff} for 1" Useless use of hash element in void context at -e line 1.
Congratulations andreas1234567, you have found a bug: map in void context silences "Useless use of hash element in void context".

Please use perlbug and report this bug :)

A similar bug is #68592: 'Useless use of not in void context' should appear in more cases

Replies are listed 'Best First'.
Re^2: Possible useless use of map
by almut (Canon) on Mar 18, 2010 at 10:27 UTC

    Actually, I'm a bit surprised that I do get the same warning with a slightly modified variant:

    $ perl -Mstrict -Mwarnings -MData::Dumper -le 'my $hr; $hr->{stuff}{fo +o} for 1; print Dumper $hr' Useless use of hash element in void context at -e line 1. $VAR1 = { 'stuff' => {} };

    As it autovivifies, it's not "useless", strictly speaking...  Also, what about (intended) side effects with tied hashes?

      As it autovivifies, it's not "useless", strictly speaking..

      By that logic, the following shouldn't warn since calling f() isn't useless:
      $ perl -c -we'f()+123' Useless use of addition (+) in void context at -e line 1. -e syntax OK

      You're mistaken about what gives the warning. The op that does the autovivification is not the one issuing the warning. It's the access of the foo element that issues the warning, and it's indeed useless to access the foo element.

      $ perl -we'my $hr; $hr->{stuff}{foo}' Useless use of hash element in void context at -e line 1.

      is basically equivalent to

      $ perl -we'my $hr; $_ = \%{ $hr }; $_ = \%{ $_->{stuff} }; $_->{foo};' Useless use of hash element in void context at -e line 1.

      The last bit is clearly useless.

      If you prefer a diagram,

      ___________________ scalar context pad fetch. autovivifies / ________________ deref | / ____________ scalar context hash fetch. autovivifies | | / _______ deref | | | / ____ void context hash fetch. warns. | | | | / |--|-|------|-|----| $hr->{stuff}->{foo};

      Similar, without useless bits:

      $hr->{stuff} //= {};

      Also, what about (intended) side effects with tied hashes?

      Warnings aren't always accurate. That's why you can turn them off.

      Update: Additions for the sake of clarity.

      Well the first version also auotovivifies.... i'm not sure what you mean about tied hashes.

        No, $hr->{stuff} alone doesn't autovivify the element. It's the dereferencing operation

        $hr->{stuff}->{foo} ^^

        that autovivifies, not merely accessing the hash element.

        As for side effects with tied hashes, I mean that arbitrary code could be associated with the tied read operation.

Re^2: Possible useless use of map
by JavaFan (Canon) on Mar 18, 2010 at 14:39 UTC
    What bug? In:
    map {$hr->{stuff}} 1
    there is no hash element in void context. It's in list context.
      perl590delta says map in void context is no longer expensive. map is now context aware, and will not construct a list if called in void context.

      if there is no list, why is there list context?

        Just like about any other operator in Perl, map imposes a certain context on its operands, regardless of the context it itself is in. In:
        map {$hash->{foo}} 1;
        there are actually two lists, both containing a single element: the first list consists of $hash->{foo}, the second of 1.

        Think of it this way, if map would not provide list context to its inner block, the following wouldn't do what it does now:

        %h = map {$_ => 1} qw[foo bar baz];

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://829366]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-04-19 04:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found