Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@{undef} inconsistently strict #6094

Open
p5pRT opened this issue Nov 23, 2002 · 23 comments
Open

@{undef} inconsistently strict #6094

p5pRT opened this issue Nov 23, 2002 · 23 comments
Labels
Closable? We might be able to close this ticket, but we need to check with the reporter distro-Linux Stalled type-core

Comments

@p5pRT
Copy link

p5pRT commented Nov 23, 2002

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

Searchable as RT18635$

@p5pRT
Copy link
Author

p5pRT commented Nov 23, 2002

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
Copy link
Author

p5pRT commented Nov 25, 2002

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
Copy link
Author

p5pRT commented Nov 25, 2002

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
Copy link
Author

p5pRT commented Nov 25, 2002

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
Copy link
Author

p5pRT commented Nov 25, 2002

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
Copy link
Author

p5pRT commented Nov 25, 2002

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
Copy link
Author

p5pRT commented Nov 25, 2002

From @rgs

Nicholas Clark <nick@​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
Copy link
Author

p5pRT commented Nov 25, 2002

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
Copy link
Author

p5pRT commented Nov 25, 2002

From @rgs

"Orton, Yves" <yves.orton@​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'
<nothing>

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
Copy link
Author

p5pRT commented Nov 29, 2002

From @nwc10

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

Nicholas Clark <nick@​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
Copy link
Author

p5pRT commented Nov 29, 2002

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
Copy link
Author

p5pRT commented Feb 19, 2004

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
Copy link
Author

p5pRT commented Mar 12, 2009

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
Copy link
Author

p5pRT commented Mar 12, 2009

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
Copy link
Author

p5pRT commented Mar 12, 2009

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

@p5pRT
Copy link
Author

p5pRT commented Mar 12, 2009

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
Copy link
Author

p5pRT commented Mar 12, 2009

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
Copy link
Author

p5pRT commented Mar 13, 2009

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
Copy link
Author

p5pRT commented Mar 13, 2009

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
Copy link
Author

p5pRT commented Mar 13, 2009

From @davidnicol

On Thu, Mar 12, 2009 at 9​:25 PM, Yitzchak Scott-Thoennes
<sthoenna@​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
Copy link
Author

p5pRT commented Aug 24, 2011

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
Copy link
Author

p5pRT commented Aug 24, 2011

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
Copy link
Author

p5pRT commented Aug 25, 2011

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

@toddr toddr added Stalled Closable? We might be able to close this ticket, but we need to check with the reporter labels Feb 4, 2020
@xenu xenu removed the affects-5.8 label Nov 19, 2021
@xenu xenu removed the Severity Low label Dec 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closable? We might be able to close this ticket, but we need to check with the reporter distro-Linux Stalled type-core
Projects
None yet
Development

No branches or pull requests

3 participants