Warning scalar value @h{...} better written as $h{...}

W

Wolf Behrenhoff

Hello all,

why does the following code produce a warning?

perl -wle'opendir $d, "/home";my %h;@h{readdir $d}=();print for keys %h'
Scalar value @h{readdir $d} better written as $h{readdir $d} at -e line 1.

Of course, one must not follow the advice because that would do
something different.

One can of course write
@h{@{[readdir $d]}}=();
to suppress the warning, but that looks a bit complicated.

Tested with v5.8.8 and v5.10.1.

Wolf
 
R

Rainer Weikusat

Wolf Behrenhoff said:
perl -wle'opendir $d, "/home";my %h;@h{readdir $d}=();print for keys %h'
Scalar value @h{readdir $d} better written as $h{readdir $d} at -e
line 1.

My guess (I haven't checked the code) would be that it wrongly
considers 'readdir $d' to be a string which will be autoquoted when
used as a hash subscript and because of this, thinks you are using a
slice where accessing a single element would be sufficient.

[...]
One can of course write
@h{@{[readdir $d]}}=();
to suppress the warning, but that looks a bit complicated.

Another workaround is to make 'readdir' look like a function call,
that is, use readdir($d), at least for 5.10.1.
 
R

Rainer Weikusat

Rainer Weikusat said:
My guess (I haven't checked the code) would be that it wrongly
considers 'readdir $d' to be a string which will be autoquoted when
used as a hash subscript

I just had a look at the code because I was curious and the following
check is used in order to determine if the operation inside the
slice-defining subscript cannot possibly yield more than one value:

if (*s == '[' || *s == '{') {
if (ckWARN(WARN_SYNTAX)) {
const char *t = s + 1;
while (*t && (isALNUM_lazy_if(t,UTF) || strchr(" \t$#+-'\"", *t)))
t++;
if (*t == '}' || *t == ']') {
t++;
PL_bufptr = PEEKSPACE(PL_bufptr); /* XXX can realloc */
Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Scalar value %.*s better written as $%.*s",
(int)(t-PL_bufptr), PL_bufptr,
(int)(t-PL_bufptr-1), PL_bufptr+1);
}
}
}

This is, of course, just plain broken:

[rw@sapphire]~ $perl -we 'my @a; @a[1 + 1] = 2;'
Scalar value @a[1 + 1] better written as $a[1 + 1] at -e line 1.
[rw@sapphire]~ $perl -we 'my @a; @a[(1 + 1)] = 2;'
[rw@sapphire]~ $
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top