Open p5pRT opened 21 years ago
$ 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?
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
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/
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
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
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
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.
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
"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'
\
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.)
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/
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.
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
$ 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
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
The RT System itself - Status changed from 'new' to 'open'
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
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
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).
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?
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.
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.
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.
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).
Migrated from rt.perl.org#18635 (status was 'open')
Searchable as RT18635$