in reply to Re: Incorrect warning when using hash slices?
in thread Incorrect warning when using hash slices?

I'm wondering if this relates to perl having difficulty distinguishing between the qw## operator versus a bare hash key that looks like qw##. I guess there's not much to wonder about there. That seems to be what's happening:

use 5.010_001; use strict; use warnings; my %hash = qw/ one um two dois /; { local $, = "\t"; say @hash{ qw# one two # }; say @hash{ (qw# one two #) }; }

Output is:

Scalar value @hash{ qw# one two # } better written as $hash{ qw# one t +wo # } at mytest.pl line 12. um dois um dois

Only one warning. The second hash slice uses parens to disambiguate the intent of whether qw## represents a hash key, or a qw## operator.

By the way, if I use diagnostics, I get:

Scalar value @hash{ qw# one two # } better written as $hash{ qw# one two # } at mytest.pl line 13 (#1) (W syntax) You've used a hash slice (indicated by @) to select a single element of a hash. Generally it's better to ask for a scalar value (indicated by $). The difference is that $foo{&bar} always behaves like a scalar, both when assigning to it and when evaluating its argument, while @foo{&bar} behaves like a list when you assign to it, and provides a list context to its subscript, which can do weird things if you're expecting only one subscript. On the other hand, if you were actually hoping to treat the hash element as a list, you need to look into how references work, because Perl will not magically convert between scalars and lists for you. See perlref.

...which seems to support that qr## is being seen by the warnings pragma as a hash key instead of a list constructor. On the other hand, perl still sees it as a list constructor, and does the right thing. I know just about zero with regards to Perl's internal code, but it would seem the culprit is within the warnings mechanism.

But I'm putting this out there for discussion's sake. I'm as curious as anyone and am just speculating reasons.


Dave

Replies are listed 'Best First'.
Re^3: Incorrect warning when using hash slices?
by moritz (Cardinal) on Apr 27, 2011 at 08:08 UTC
    I'm wondering if this relates to perl having difficulty distinguishing between the qw## operator versus a bare hash key that looks like qw##.

    B::Deparse to the rescue:

    $ perl -MO=Deparse -wE '$foo{a}=1; $foo{b}=2; say join",", @foo{qw#a b +#}' BEGIN { $^W = 1; } BEGIN { $^H{'feature_unicode'} = q(1); $^H{'feature_say'} = q(1); $^H{'feature_state'} = q(1); $^H{'feature_switch'} = q(1); } $foo{'a'} = 1; $foo{'b'} = 2; say join(',', @foo{'a', 'b'}); -e syntax OK

    So it deparses correctly to @foo{'a', 'b'}

    When I used / instead of # as a delimiter, I get the same deparse, and no warning on running. So I don't see parsing issues as the reason for this bug.