Perl / perl5

šŸŖ The Perl programming language
https://dev.perl.org/perl5/
Other
1.94k stars 554 forks source link

@{undef} inconsistently strict #6094

Open p5pRT opened 21 years ago

p5pRT commented 21 years ago

Migrated from rt.perl.org#18635 (status was 'open')

Searchable as RT18635$

p5pRT commented 21 years ago

From @nwc10

Created by @nwc10

$ perl5.8.0 -lwe 'use strict; push @​$a\, "foo"; print $a' ARRAY(0xf4284) $ perl -le 'use strict; 2 == $a->[1]; print $a' ARRAY(0xf4284) $ perl5.8.0 -lwe 'use strict; print @​$a; print $a' Can't use an undefined value as an ARRAY reference at -e line 1.

This isn't consistent. Why?

Perl Info ``` Flags: category=core severity=low This perlbug was built using Perl v5.8.0 - Sat Jul 13 15:53:56 BST 2002 It is being executed now by Perl v5.8.0 - Fri Jul 19 22:00:42 BST 2002. Site configuration information for perl v5.8.0: Configured by nick at Fri Jul 19 22:00:42 BST 2002. Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration: Platform: osname=linux, osvers=2.4.18-rmk7, archname=armv4l-linux uname='linux bagpuss.unfortu.net 2.4.18-rmk7 #10 sun jun 23 21:43:05 bst 2002 armv4l unknown ' config_args='-Dcc=ccache gcc-3.0 -Dld=gcc-3.0 -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@ccl4.org -Dperladmin=nick@ccl4.org -Dinc_version_list= -Dinc_version_list_init=0 -Doptimize=-Os -de -Uusethreads' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='ccache gcc-3.0', ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-Os', cppflags='-fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='3.0.4', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='gcc-3.0', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -lgdbm -ldbm -ldb -ldl -lm -lc -lcrypt -lutil perllibs=-lnsl -ldl -lm -lc -lcrypt -lutil libc=/lib/libc-2.2.4.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.2.4' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: DEVEL17513 @INC for perl v5.8.0: /usr/local/lib/perl5/5.8.0/armv4l-linux /usr/local/lib/perl5/5.8.0 /usr/local/lib/perl5/site_perl/5.8.0/armv4l-linux /usr/local/lib/perl5/site_perl/5.8.0 /usr/local/lib/perl5/site_perl . Environment for perl v5.8.0: HOME=/home/nick LANG (unset) LANGUAGE (unset) LC_CTYPE=en_GB.ISO-8859-1 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/nick/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/sbin:/usr/sbin:/usr/local/sbin PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 21 years ago

From @eserte

Nicholas Clark (via RT) \perlbug@​perl\.org writes​:

# New Ticket Created by Nicholas Clark # Please include the string​: [perl #18635] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=18635 >

This is a bug report for perl from nick@​ccl4.org\, generated with the help of perlbug 1.34 running under perl v5.8.0.

----------------------------------------------------------------- [Please enter your report here]

$ perl5.8.0 -lwe 'use strict; push @​$a\, "foo"; print $a' ARRAY(0xf4284) $ perl -le 'use strict; 2 == $a->[1]; print $a' ARRAY(0xf4284) $ perl5.8.0 -lwe 'use strict; print @​$a; print $a' Can't use an undefined value as an ARRAY reference at -e line 1.

This isn't consistent. Why?

$a and $b are special variables (for sort) and do not need to be declared.

Regards\,   Slaven

-- Slaven Rezic - slaven.rezic@​berlin.de

  Berlin Perl Mongers - http​://berliner.pm.org

p5pRT commented 21 years ago

From sburke@cpan.org

At 10​:10 2002-11-25 +0100\, Slaven Rezic wrote​:

# New Ticket Created by Nicholas Clark # Please include the string​: [perl #18635] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=18635 > [...] $ perl5.8.0 -lwe 'use strict; push @​$a\, "foo"; print $a' ARRAY(0xf4284) $ perl -le 'use strict; 2 == $a->[1]; print $a' ARRAY(0xf4284) $ perl5.8.0 -lwe 'use strict; print @​$a; print $a' Can't use an undefined value as an ARRAY reference at -e line 1.

This isn't consistent. Why?

$a and $b are special variables (for sort) and do not need to be declared.

I don't think the choice of variable name is what he means. I think he means something like​: "Why does treating undef as an arrayref work in the first two cases\, but not the latter two?"

I feel like Perl is doing the right thing in all three cases\, but I can't explain why\, at least not in terms that I find satisfactory and non-tautological.

-- Sean M. Burke http​://search.cpan.org/author/sburke/

p5pRT commented 21 years ago

From @demerphq

Sean M. Burke said on 25 November 2002 10​:35

At 10​:10 2002-11-25 +0100\, Slaven Rezic wrote​:

# New Ticket Created by Nicholas Clark # Please include the string​: [perl #18635] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=18635 > [...] $ perl5.8.0 -lwe 'use strict; push @​$a\, "foo"; print $a' ARRAY(0xf4284) $ perl -le 'use strict; 2 == $a->[1]; print $a' ARRAY(0xf4284) $ perl5.8.0 -lwe 'use strict; print @​$a; print $a' Can't use an undefined value as an ARRAY reference at -e line 1.

This isn't consistent. Why?

$a and $b are special variables (for sort) and do not need to be declared.

I don't think the choice of variable name is what he means.
I think he means something like​: "Why does treating undef as an arrayref work in the first two cases\, but not the latter two?"

I feel like Perl is doing the right thing in all three cases\, but I can't explain why\, at least not in terms that I find satisfactory and non-tautological.

At first I thought you were correct. The rule being "autovification on write but not on read". But on reflection I realized that this is wrong (consider if ($a->{a}{b}{c}) and I now think that Nick is correct.

Either all aspects of a read should not auto vivify (prepare for half the world to have their code broken :( or all aspects of a read _should_ autovifify. Im guessing based on my own experiences that changing the behaviour of

  undef $a;   if (@​$a) {

to autovifiy $a wouldnt actually break any existing code as inorder to work it will have been written defensively already\, ie either

  if (@​{$a||[]}) {

Or the clumsier\,

  $a=[] unless defined $a;   if (@​$a) {

Cheers\, Yves

p5pRT commented 21 years ago

From @nwc10

On Mon\, Nov 25\, 2002 at 10​:26​:43AM -0000\, Orton\, Yves wrote​:

Sean M. Burke said on 25 November 2002 10​:35

At 10​:10 2002-11-25 +0100\, Slaven Rezic wrote​:

# New Ticket Created by Nicholas Clark # Please include the string​: [perl #18635] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=18635 > [...] $ perl5.8.0 -lwe 'use strict; push @​$a\, "foo"; print $a' ARRAY(0xf4284) $ perl -le 'use strict; 2 == $a->[1]; print $a' ARRAY(0xf4284) $ perl5.8.0 -lwe 'use strict; print @​$a; print $a' Can't use an undefined value as an ARRAY reference at -e line 1.

This isn't consistent. Why?

I feel like Perl is doing the right thing in all three cases\, but I can't explain why\, at least not in terms that I find satisfactory and non-tautological.

At first I thought you were correct. The rule being "autovification on write but not on read". But on reflection I realized that this is wrong (consider if ($a->{a}{b}{c}) and I now think that Nick is correct.

It seems that the current rule is autovivification is OK for element access as an RVALUE\, but not for whole array access as an RVALUE (and OK as an LVALUE)

which wasn't what I expected. One part of my brain knew that I'd had to code things like $a||=[] inside lookups\, whereas another knew that defined ($a->{a}{b}{c}) may create $a->{a}{b}\, but the two didn't seem to have got together and gone "hey\, this is inconsistent"

Either all aspects of a read should not auto vivify (prepare for half the world to have their code broken :( or all aspects of a read _should_

or this​:

@​$a = ...;

should fail (ie autovivification for whole arrays not allowed)

autovifify. Im guessing based on my own experiences that changing the behaviour of

undef $a; if (@​$a) {

to autovifiy $a wouldnt actually break any existing code as inorder to work it will have been written defensively already\, ie either

if (@​{$a||[]}) {

Or the clumsier\,

$a=[] unless defined $a; if (@​$a) {

I agree. I can't see anything wrong with your reasoning. I think that changing @​$a to auto-vivify would only break scripts that either relied on evals failing\, or ran under no strict 'refs' and relied on @​$a not changing $a.

Nicholas Clark

p5pRT commented 21 years ago

From @demerphq

Nicholas Clark said on 25 November 2002 11​:57

On Mon\, Nov 25\, 2002 at 10​:26​:43AM -0000\, Orton\, Yves wrote​:

Sean M. Burke said on 25 November 2002 10​:35

At 10​:10 2002-11-25 +0100\, Slaven Rezic wrote​:

# New Ticket Created by Nicholas Clark # Please include the string​: [perl #18635] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt2/Ticket/Display.html?id=18635 > [...] $ perl5.8.0 -lwe 'use strict; push @​$a\, "foo"; print $a' ARRAY(0xf4284) $ perl -le 'use strict; 2 == $a->[1]; print $a' ARRAY(0xf4284) $ perl5.8.0 -lwe 'use strict; print @​$a; print $a' Can't use an undefined value as an ARRAY reference at -e line 1.

This isn't consistent. Why?

I feel like Perl is doing the right thing in all three cases\, but I can't explain why\, at least not in terms that I find satisfactory and non-tautological.

At first I thought you were correct. The rule being "autovification on write but not on read". But on reflection I realized that this is wrong (consider if ($a->{a}{b}{c}) and I now think that Nick is correct.

It seems that the current rule is autovivification is OK for element access as an RVALUE\, but not for whole array access as an RVALUE (and OK as an LVALUE)

which wasn't what I expected. One part of my brain knew that I'd had to code things like $a||=[] inside lookups\, whereas another knew that

$a||=[]

Hmm\, for some bizarre reason that one never occured to me. :-)

defined ($a->{a}{b}{c}) may create $a->{a}{b}\, but the two didn't seem to have got together and gone "hey\, this is inconsistent"

Exactly. Personally I think that $a->{a}{b} should not be created on a read like $a->{a}{b}{c}. But i know how many scripts such a change would break so ive gotten over it.

Either all aspects of a read should not auto vivify (prepare for half the world to have their code broken :( or all aspects of a read _should_

or this​:

@​$a = ...;

should fail (ie autovivification for whole arrays not allowed)

Well\, I'm doubtful that this is the best strategy. I think autovivfy on write is very useful. Consider that a common idiom when doing HOL's is

  push @​{$hash{$key}}\,$item;

So making autovivfy on read consistant makes more sense to me.

autovifify. Im guessing based on my own experiences that changing the behaviour of

undef $a; if (@​$a) {

to autovifiy $a wouldnt actually break any existing code as inorder to work it will have been written defensively already\, ie either

if (@​{$a||[]}) {

Or the clumsier\,

$a=[] unless defined $a; if (@​$a) {

I agree. I can't see anything wrong with your reasoning. I think that changing @​$a to auto-vivify would only break scripts that either relied on evals failing\, or ran under no strict 'refs' and relied on @​$a not changing $a.

Doh. Of course. Either way im betting that code that depends on the above types of behaviour is pretty rare.

Yves

p5pRT commented 21 years ago

From @rgs

Nicholas Clark \nick@&#8203;ccl4\.org wrote​:

Or the clumsier\,

$a=[] unless defined $a;

$a //= []; # ;-)

if (@​$a) {

I agree. I can't see anything wrong with your reasoning. I think that changing @​$a to auto-vivify would only break scripts that either relied on evals failing\, or ran under no strict 'refs' and relied on @​$a not changing $a.

strict 'refs' prohibits only symbolic references. It has no business prohibiting @​$x / $$x / %$x when $x is undefined. The question whether a readonly @​$a should autovivify is orthogonal to strictures.

My personal opinion on that last question is that new cases for autovivification shouldn't be added\, or very carefully.

p5pRT commented 21 years ago

From @demerphq

Rafael Garcia-Suarez said

My personal opinion on that last question is that new cases for autovivification shouldn't be added\, or very carefully.

I agree in general. But if its to make autovification more consistant and thus easier to understand and teach it seems to be justified. Do you agree or was your comment an indication that you think it isn't worthwhile in this case?

And personally i would like it if stuff like​:

  unless (@​{$hash{$key}}) {

didn't raise an error when $hash{$key} is undef. If only cause its a pain to explain to a perl newbie what

  unless ( @​{ $hash{$key} || [] } ) {

does...

Yves

p5pRT commented 21 years ago

From @rgs

"Orton\, Yves" \yves\.orton@&#8203;mciworldcom\.de wrote​:

Rafael Garcia-Suarez said

My personal opinion on that last question is that new cases for autovivification shouldn't be added\, or very carefully.

I agree in general. But if its to make autovification more consistant and thus easier to understand and teach it seems to be justified. Do you agree or was your comment an indication that you think it isn't worthwhile in this case?

I think that strictures shouldn't interfere with autovivification. The fact that @​$x autovivifies an undefined $x is not related with symbolic references\, hence I think it should be modified so that strict 'refs' doesn't interfere with it. Practically this means that strict 'refs' will be less strict\, and that the error message "Can't use an undefined value as %s reference" will go away\, and that doesn't sound like a good thing when I say it that way.

This crosses another known bug :

$ perl -Mstrict=refs -le 'my $x="a";print $$x' Can't use string ("a") as a SCALAR ref while "strict refs" in use at -e line 1. $ perl -Mstrict=refs -le 'my $x="a";print defined $$x' \

The latest case should trigger an error (even if there's no autovivification here\, due to the defined()) because a symbolic reference is involved.

(I've a patch to address this latest case\, but it breaks some tests.)

p5pRT commented 21 years ago

From @nwc10

On Mon\, Nov 25\, 2002 at 02​:23​:28PM +0100\, Rafael Garcia-Suarez wrote​:

Nicholas Clark \nick@&#8203;ccl4\.org wrote​:

Or the clumsier\,

$a=[] unless defined $a;

$a //= []; # ;-)

if (@​$a) {

I agree. I can't see anything wrong with your reasoning. I think that changing @​$a to auto-vivify would only break scripts that either relied on evals failing\, or ran under no strict 'refs' and relied on @​$a not changing $a.

strict 'refs' prohibits only symbolic references. It has no business prohibiting @​$x / $$x / %$x when $x is undefined. The question whether a readonly @​$a should autovivify is orthogonal to strictures.

I agree that it's orthogonal.

I found another inconsistency​:

$ perl -lwe 'use strict; print @​$a' Name "main​::a" used only once​: possible typo at -e line 1. Can't use an undefined value as an ARRAY reference at -e line 1.

$ perl -lwe 'use strict; print foreach @​$a' Name "main​::a" used only once​: possible typo at -e line 1.

My personal opinion on that last question is that new cases for autovivification shouldn't be added\, or very carefully.

I think I'm only asking that it be legal to do it without warnings under strict. I don't think that I'm asking for $a to get written back to with an autovivified array reference.

Nicholas Clark -- INTERCAL better than perl? http​://www.perl.org/advocacy/spoofathon/

p5pRT commented 21 years ago

From @rgs

Nicholas Clark wrote​:

I found another inconsistency​:

$ perl -lwe 'use strict; print @​$a' Name "main​::a" used only once​: possible typo at -e line 1. Can't use an undefined value as an ARRAY reference at -e line 1.

$ perl -lwe 'use strict; print foreach @​$a' Name "main​::a" used only once​: possible typo at -e line 1.

Looking at pp_rv2av\, and the other pp_rv2?v\, the errors and warnings are thrown only under some convoluted conditions.

It's possible by inspecting the code to work out a full matrix opflags x scalar value :   OPf_REF OPf_MOD OPf_SPECIAL ... reference DIE / WARN / NOTHING with/without strict "refs" scalar for %$x\, $$x\, @​$x\, &$x\, *$x undef etc...

and then to imagine a more consistent behaviour. Then\, write coverage tests and patch pp_rv2?v accordingly.

p5pRT commented 20 years ago

From perl-5.8.0@ton.iguana.be

Created by perl-5.8.0@ton.iguana.be

Why doesn't this actually work​:

perl -e '$x = ($u=undef)->{foo}' Can't use an undefined value as a HASH reference at -e line 1.

while this is (of course) fine​:

perl -e '$u = undef; $x = $u->{foo}'

isn't the result of an assignment supposed to be a proper lvalue ?

perldoc perlref definitely discusses autovivication in terms of lvalues\, so this feels like a bug to me.

This bug may be related to bug 18635​: http​://dev.perl.org/perl5/list-summaries/2002/p5p-200211-4.html http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-11/msg00855.html

Perl Info ``` Flags: category=core severity=low Site configuration information for perl v5.8.2: Configured by ton at Sun Jan 4 19:19:06 CET 2004. Summary of my perl5 (revision 5.0 version 8 subversion 2) configuration: Platform: osname=linux, osvers=2.6.0, archname=i686-linux-64int-ld uname='linux quasar 2.6.0 #3 thu dec 18 18:22:48 cet 2003 i686 gnulinux ' config_args='' hint=recommended, useposix=true, d_sigaction=define usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=define use64bitall=undef uselongdouble=define usemymalloc=y, bincompat5005=undef Compiler: cc='cc', ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2 -fomit-frame-pointer', cppflags='-fno-strict-aliasing -I/usr/local/include' ccversion='', gccversion='3.4.0 20031231 (experimental)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long long', ivsize=8, nvtype='long double', nvsize=12, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc libc=/lib/libc-2.3.2.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.3.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic' cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib' Locally applied patches: @INC for perl v5.8.2: /usr/lib/perl5/5.8.2/i686-linux-64int-ld /usr/lib/perl5/5.8.2 /usr/lib/perl5/site_perl/5.8.2/i686-linux-64int-ld /usr/lib/perl5/site_perl/5.8.2 /usr/lib/perl5/site_perl . Environment for perl v5.8.2: HOME=/home/ton LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/ton/bin.Linux:/home/ton/bin:/home/ton/bin.SampleSetup:/usr/local/bin:/usr/local/sbin:/usr/local/jre/bin:/home/oracle/product/9.0.1/bin:/usr/local/ar/bin:/usr/games/bin:/usr/X11R6/bin:/usr/share/bin:/usr/bin:/usr/sbin:/bin:/sbin:. PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 15 years ago

From @nwc10

Created by @nwc10

$ cat -n fail.pl   1 use strict;   2 my $valid = $a->[0];   3 my @​invalid = @​{$b->[0]}; $ perl fail.pl Can't use an undefined value as an ARRAY reference at fail.pl line 3.

Note the line number.

How can it be anything *but* a *bug* that one sort of undefined value dereference *in the same expression* is valid under use strict refs\, but another is not?

No "LVALUE" or "RVALUE" distinction here. Why is $b->[0] considered kosher\, but @​$b not?

Nicholas Clark

Perl Info ``` Flags: category=core severity=medium Site configuration information for perl 5.11.0: Configured by nick at Wed Mar 11 18:42:13 GMT 2009. Summary of my perl5 (revision 5 version 11 subversion 0) configuration: Commit id: 7bb74d351eaaa2da4a13b7b3160774cdbaf460b0 Platform: osname=linux, osvers=2.6.18-xenu, archname=x86_64-linux-thread-multi uname='linux zazen 2.6.18-xenu #1 smp thu oct 4 12:23:41 bst 2007 x86_64 gnulinux ' config_args='-Dusedevel=y -Dcc=ccache gcc -Dld=gcc -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@ccl4.org -Dperladmin=nick@ccl4.org -Dinc_version_list= -Dinc_version_list_init=0 -Doptimize=-g -Dusethreads -Duse64bitall -Accflags=-DNO_MATHOMS -Uusemymalloc -Duseperlio -Dprefix=~/Sandpit/snap5.9.x-GitLive-blead-759-g7bb74d3 -Dinstallman1dir=none -Dinstallman3dir=none -Uuserelocatableinc -de' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='ccache gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DNO_MATHOMS -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-g', cppflags='-D_REENTRANT -D_GNU_SOURCE -DNO_MATHOMS -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.1.2 20061115 (prerelease) (Debian 4.1.1-21)', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='gcc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /lib64 /usr/lib64 libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lpthread -lc perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/libc-2.3.6.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.3.6' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -g -L/usr/local/lib -fstack-protector' Locally applied patches: PERL_GIT_UNPUSHED_COMMITS /* do not remove this line */ PERL_GIT_UNCOMMITTED_CHANGES /* do not remove this line */ @INC for perl 5.11.0: lib /home/nick/Sandpit/snap5.9.x-GitLive-blead-759-g7bb74d3/lib/perl5/site_perl/5.11.0/x86_64-linux-thread-multi /home/nick/Sandpit/snap5.9.x-GitLive-blead-759-g7bb74d3/lib/perl5/site_perl/5.11.0 /home/nick/Sandpit/snap5.9.x-GitLive-blead-759-g7bb74d3/lib/perl5/5.11.0/x86_64-linux-thread-multi /home/nick/Sandpit/snap5.9.x-GitLive-blead-759-g7bb74d3/lib/perl5/5.11.0 . Environment for perl 5.11.0: HOME=/home/nick LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/nick/bin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/local/sbin:/sbin:/usr/sbin PERL_BADLANG (unset) SHELL=/bin/bash ```
p5pRT commented 15 years ago

From Robin.Barker@npl.co.uk

Indexing auto vivifies\, plain derefencing doesn't.

perl -Mstrict -le "my $x; ${$x}; print $x" Can't use an undefined value as a SCALAR reference at -e line 1.

perl -Mstrict -le "my $x; @​{$x}; print $x" Can't use an undefined value as an ARRAY reference at -e line 1.

perl -Mstrict -le "my $x; ${$x}[0]; print $x" ARRAY(0x2261a0)

perl -Mstrict -le "my $x; $x->[0]; print $x" ARRAY(0x2261a0)

perl -Mstrict -le "my $x; %{$x}; print $x" Can't use an undefined value as a HASH reference at -e line 1.

perl -Mstrict -le "my $x; ${$x}{'foo'}; print $x" HASH(0x2261a0)

perl -Mstrict -le "my $x; @​{$x}{'foo'\,'bar'}; print $x" HASH(0x226190)

perl -Mstrict -le "my $x; $x->{'foo'}; print $x" HASH(0x2261a0)

Robin

p5pRT commented 15 years ago

The RT System itself - Status changed from 'new' to 'open'

p5pRT commented 15 years ago

From @nwc10

On Thu\, Mar 12\, 2009 at 05​:12​:09PM -0000\, Robin Barker wrote​:

Indexing auto vivifies\, plain derefencing doesn't.

perl -Mstrict -le "my $x; ${$x}; print $x" Can't use an undefined value as a SCALAR reference at -e line 1.

perl -Mstrict -le "my $x; @​{$x}; print $x" Can't use an undefined value as an ARRAY reference at -e line 1.

perl -Mstrict -le "my $x; ${$x}[0]; print $x" ARRAY(0x2261a0)

perl -Mstrict -le "my $x; $x->[0]; print $x" ARRAY(0x2261a0)

$ perl -Mstrict -le 'my $x; @​{$x}; print $x' Can't use an undefined value as an ARRAY reference at -e line 1.

Yes\, except plain dereferencing *does* in LVALUE context​:

$ perl -Mstrict -le 'my $x; 1 foreach @​{$x}; print $x' ARRAY(0x504290)

Or as the argument to defined​:

$ perl -Mstrict -le 'my $x; defined @​{$x}; print $x' ARRAY(0x504290)

So why are indexing and defined special? Are they the only exceptions to the exception?

Nicholas Clark

p5pRT commented 15 years ago

From chromatic@wgz.org

On Thursday 12 March 2009 06​:15​:05 Nicholas Clark wrote​:

[Please describe your issue here]

$ cat -n fail.pl 1 use strict; 2 my $valid = $a->[0]; 3 my @​invalid = @​{$b->[0]}; $ perl fail.pl Can't use an undefined value as an ARRAY reference at fail.pl line 3.

Note the line number.

Also note that the error message doesn't include the offending variable name.

-- c

p5pRT commented 15 years ago

From @ysth

On Thu\, March 12\, 2009 10​:18 am\, Nicholas Clark wrote​:

On Thu\, Mar 12\, 2009 at 05​:12​:09PM -0000\, Robin Barker wrote​:

Indexing auto vivifies\, plain derefencing doesn't.

So why are indexing and defined special? Are they the only exceptions to the exception?

My impression is that the general intent is that modification operations autovivify and non-modification operations not do so. But we are not entirely consistent. And in some situations ($#$x\, keys(%$x))\, we don't know whether we will be modifying or not (when those are used as lvalues).

p5pRT commented 15 years ago

From @ysth

On Thu\, March 12\, 2009 6​:15 am\, Nicholas Clark wrote​:

$ cat -n fail.pl 1 use strict; 2 my $valid = $a->[0]; 3 my @​invalid = @​{$b->[0]}; $ perl fail.pl Can't use an undefined value as an ARRAY reference at fail.pl line 3.

Note the line number.

How can it be anything *but* a *bug* that one sort of undefined value dereference *in the same expression* is valid under use strict refs\, but another is not?

No "LVALUE" or "RVALUE" distinction here. Why is $b->[0] considered kosher\, but @​$b not?

@​$b does autovivify when it is modifying​:

$ perl -wl use strict; my $b; @​{$b->[0]} = (); print $b; __END__ ARRAY(0x604290)

It makes sense to me that it does give an error when it is *not* autovivifying. Are you arguing that it should not? Or that it should autovivify even in your @​invalid = case?

p5pRT commented 15 years ago

From @davidnicol

On Thu\, Mar 12\, 2009 at 9​:25 PM\, Yitzchak Scott-Thoennes \sthoenna@&#8203;efn\.org wrote​:

Indexing auto vivifies\, plain derefencing doesn't.

and indexing only autovivs as an Lvalue\, but strict doesn't mind.

and the violation in @​{$b->[0]} was misread by the OP; the same error would occur with @​$b.

$ perl -l   use strict;   our ($c\,$d\,$e);   my $valid = $c->[0];   print scalar @​$c;   print scalar (@​$d = (1\,2\,3));   my @​invalid = @​$e; __END__ 0 3 Can't use an undefined value as an ARRAY reference at - line 6.

p5pRT commented 13 years ago

From @cpansprout

On Mon Nov 25 05​:28​:08 2002\, rafael wrote​:

strict 'refs' prohibits only symbolic references. It has no business prohibiting @​$x / $$x / %$x when $x is undefined.

This isnā€™t directly related to the original ticket\, and I know Iā€™m responding 9 years late\, but is there a consensus that strict has no business prohibiting those? Your reasoning makes sense\, but I wanted to check first before I start making changes.

Currently we have this consistency\, which has nothing to do with symbolic refs​:

Pint​:perl.git sprout$ perl -le 'print @​$x'

Pint​:perl.git sprout$ perl -Mstrict=refs -le 'print @​$x' Can't use an undefined value as an ARRAY reference at -e line 1.

p5pRT commented 13 years ago

From @cpansprout

On Tue Aug 23 17​:01​:10 2011\, sprout wrote​:

On Mon Nov 25 05​:28​:08 2002\, rafael wrote​:

strict 'refs' prohibits only symbolic references. It has no business prohibiting @​$x / $$x / %$x when $x is undefined.

This isnā€™t directly related to the original ticket\, and I know Iā€™m responding 9 years late\, but is there a consensus that strict has no business prohibiting those? Your reasoning makes sense\, but I wanted to check first before I start making changes.

Currently we have this consistency\, which has nothing to do with symbolic refs​:

Pint​:perl.git sprout$ perl -le 'print @​$x'

Pint​:perl.git sprout$ perl -Mstrict=refs -le 'print @​$x' Can't use an undefined value as an ARRAY reference at -e line 1.

An hour later\, Iā€™m having second thoughts. Just ignore what I wrote.

p5pRT commented 13 years ago

From @cpansprout

On Thu Mar 12 06​:15​:02 2009\, nicholas wrote​:

$ cat -n fail.pl 1 use strict; 2 my $valid = $a->[0]; 3 my @​invalid = @​{$b->[0]}; $ perl fail.pl Can't use an undefined value as an ARRAY reference at fail.pl line 3.

This look an awful lot like bug #18635\, which you reported. I donā€™t think it counts if you report the same bug twice. ;-)

Itā€™s basically the distinction between aelem (which autovivifies in rvalue context) and rv2av (which does not).