Closed p5pRT closed 22 years ago
This probably shouldn't compile\, but runs without complaint (and without any effect.) [D:\home\sthoenna]perl -wle "my $x; sub x:lvalue {$x}; \x = \1"
Just for comparison:
[D:\home\sthoenna]perl -wle "my $x; \$x = \1" Can't modify single ref constructor in scalar assignment at -e line 1\, at EOF Execution of -e aborted due to compilation errors.
sthoenna@efn.org (lists.p5p):
[D:\home\sthoenna]perl -wle "my $x; sub x:lvalue {$x}; \x = \1"
Hmph. B::Deparse can't cope with subroutine attributes.
On Wed\, Aug 09\, 2000 at 04:49:20AM +0000\, Simon Cozens wrote:
sthoenna@efn.org (lists.p5p):
[D:\home\sthoenna]perl -wle "my $x; sub x:lvalue {$x}; \x = \1"
Hmph. B::Deparse can't cope with subroutine attributes.
Now it can. Thanks\, applied.
Jarkko Hietaniemi (lists.p5p):
On Wed\, Aug 09\, 2000 at 04:49:20AM +0000\, Simon Cozens wrote:
Hmph. B::Deparse can't cope with subroutine attributes.
Now it can. Thanks\, applied.
This naughty hacker didn't provide a test suite patch. I know I'm only hacking on B because it makes me look studly\, but I might as well do the job properly:
On Fri\, Aug 11\, 2000 at 02:24:52AM +0000\, Simon Cozens wrote:
Jarkko Hietaniemi (lists.p5p):
On Wed\, Aug 09\, 2000 at 04:49:20AM +0000\, Simon Cozens wrote:
Hmph. B::Deparse can't cope with subroutine attributes.
Now it can. Thanks\, applied.
This naughty hacker didn't provide a test suite patch. I know I'm
I know I must take lessons from Mr QA Schwern: no test and/or doc\, no patch...
Thanks.
While trolling for old lvalue bugs\, I found the following example from August that never seemed to be resolved (though it provoked a B::Deparse fix\, strangely enough):
AS-T> This probably shouldn't compile\, but runs without complaint (and AS-T> without any effect.) AS-T> [D:\home\sthoenna]perl -wle "my $x; sub x:lvalue {$x}; \x = \1"
AS-T> Just for comparison:
AS-T> [D:\home\sthoenna]perl -wle "my $x; \$x = \1" AS-T> Can't modify single ref constructor in scalar assignment at -e AS-T> line 1\, at EOF AS-T> Execution of -e aborted due to compilation errors.
The first time I looked at it I didn't read it carefully and mistyped the test case\, making me think it was something I had fixed in a previous lvalue patch\, but on further reflection I don't think the problem is really related to lvalue-subroutines at all -- the thing that makes the two cases above different is that the \ in the first example is an OP_REFGEN\, while in the second it's an OP_SREFGEN. Here's another example:
perl -e '\($x\, $y) = (1\, 2)'
At the moment\, that's legal perl\, though it doesn't do anything useful (it creates temporary references\, overwrites them with integers\, and then throws them away). I think it should instead be an error\, if for no other reason that consistency with the srefgen case. The reason it's not an error is that mod() has a special case for OP_REFGEN\, which allows it to be in an assignment\, but disables the split-counting optimization (since \(@x) might have an arbitrarily large number of elements just like @x could). I can't figure out the purpose of this special case\, and it seems to predate all the recorded history of perl5 that I have easy access to (it was in 5.000). The following patch\, which removes it\, passes the test suite\, and makes the example above say
Can't modify reference constructor in scalar assignment at -e line 1\, at EOF
-- Stephen "wishing for blame logs on the alpha releases" McCamant
-- Stephen "wishing for blame logs on the alpha releases" McCamant
In alpha releases\, it was generally Mr L. W.
--- op.c.orig Wed Jan 24 23:49:46 2001 +++ op.c Thu Jan 25 00:10:53 2001
Thanks\, applied. How about a test suite addition?
"JHi" == Jarkko Hietaniemi \jhi@​iki\.fi writes:
SMcC> -- Stephen "wishing for blame logs on the alpha releases" SMcC> McCamant
JHi> In alpha releases\, it was generally Mr L. W.
Not in this case\, though! After more poking around I found where the OP_REFGEN case came from:
[snip] *** perl5a12-e/op.c Wed Aug 24 10:06:53 1994 --- perl5a12-f/op.c Thu Aug 25 09:42:19 1994 [snip] *** 852\,857 **** --- 854\,861 ---- case OP_HSLICE: case OP_NEXTSTATE: case OP_DBSTATE: + case OP_REFGEN: + case OP_SAFECHOP: modcount = 10000; break; case OP_RV2SV:
That's from patch.12f against perl5alpha12\, which was Andy Dougherty's repackaging of a patch from Mark Jeffrys which among other things added the current behavior of \ as a list operator; presumably the change was put in because \ was for the first time able to yield more than one value. Lest this seem like an empty historical exercise\, the fact that safechop() (later renamed chomp()) was added at the same time is important\, since it turns out chomp() has the same problem:
perl -e 'chomp($x\, $y) = (1\, 2);'
doesn't give an error either.
JHi> Thanks\, applied. How about a test suite addition?
The following patch fixes the chomp() problem and adds test for both.
-- Stephen McC
Looks like this patch never got applied. In any case 20000808.005 (now #3661) can be closed.
On Sat\, 27 Jan 2001 19:31:29 -0800 (PST)\, smcc@CSUA.Berkeley.EDU wrote:
"JHi" == Jarkko Hietaniemi \jhi@​iki\.fi writes:
SMcC> -- Stephen "wishing for blame logs on the alpha releases" SMcC> McCamant
JHi> In alpha releases\, it was generally Mr L. W.
Not in this case\, though! After more poking around I found where the OP_REFGEN case came from:
[snip] *** perl5a12-e/op.c Wed Aug 24 10:06:53 1994 --- perl5a12-f/op.c Thu Aug 25 09:42:19 1994 [snip] *** 852\,857 **** --- 854\,861 ---- case OP_HSLICE: case OP_NEXTSTATE: case OP_DBSTATE: + case OP_REFGEN: + case OP_SAFECHOP: modcount = 10000; break; case OP_RV2SV:
That's from patch.12f against perl5alpha12\, which was Andy Dougherty's repackaging of a patch from Mark Jeffrys which among other things added the current behavior of \ as a list operator; presumably the change was put in because \ was for the first time able to yield more than one value. Lest this seem like an empty historical exercise\, the fact that safechop() (later renamed chomp()) was added at the same time is important\, since it turns out chomp() has the same problem:
perl -e 'chomp($x\, $y) = (1\, 2);'
doesn't give an error either.
JHi> Thanks\, applied. How about a test suite addition?
The following patch fixes the chomp() problem and adds test for both.
-- Stephen McC
--- perl-current/op.c Fri Jan 26 20:26:29 2001 +++ perl-changed/op.c Sat Jan 27 19:18:51 2001 @@ -1568\,7 +1568\,6 @@ Perl_mod(pTHX_ OP *o\, I32 type) case OP_AASSIGN: case OP_NEXTSTATE: case OP_DBSTATE: - case OP_CHOMP: PL_modcount = RETURN_UNLIMITED_NUMBER; break; case OP_RV2SV: --- perl-current/t/op/ref.t Tue Dec 5 06:54:49 2000 +++ perl-changed/t/op/ref.t Sat Jan 27 19:19:18 2001 @@ -1\,6 +1\,6 @@ #!./perl
-print "1..61\n"; +print "1..62\n";
# Test glob operations.
@@ -207\,11 +207\,15 @@ print @baa == 3 ? "ok 42\n" : "not ok 42 print grep(ref($_)\, @baa) == 3 ? "ok 43\n" : "not ok 43\n"; print @bzz == 3 ? "ok 44\n" : "not ok 44\n";
+# also\, it can't be an lvalue +eval '\\($x\, $y) = (1\, 2);'; +print $@ =~ /Can\'t modify.*ref.*in.*assignment/ ? "ok 45\n" : "not ok 45\n"; + # test for proper destruction of lexical objects
-sub larry::DESTROY { print "# larry\nok 45\n"; } -sub curly::DESTROY { print "# curly\nok 46\n"; } -sub moe::DESTROY { print "# moe\nok 47\n"; } +sub larry::DESTROY { print "# larry\nok 46\n"; } +sub curly::DESTROY { print "# curly\nok 47\n"; } +sub moe::DESTROY { print "# moe\nok 48\n"; }
{ my ($joe\, @curly\, %larry); @@ -225\,13 +229\,13 @@ print "# left block\n";
# another glob test
-$foo = "not ok 48"; +$foo = "not ok 49"; { local(*bar) = "foo" } -$bar = "ok 48"; +$bar = "ok 49"; local(*bar) = *bar; print "$bar\n";
-$var = "ok 49"; +$var = "ok 50"; $_ = \$var; print $$_\,"\n";
@@ -240\,10 +244\,10 @@ print $$_\,"\n"; { package A; sub new { bless {}\, shift } - DESTROY { print "# destroying 'A'\nok 51\n" } + DESTROY { print "# destroying 'A'\nok 52\n" } package _B; sub new { bless {}\, shift } - DESTROY { print "# destroying '_B'\nok 50\n"; bless shift\, 'A' } + DESTROY { print "# destroying '_B'\nok 51\n"; bless shift\, 'A' } package main; my $b = _B->new; } @@ -255\,11 +259\,11 @@ print $$_\,"\n"; local $SIG{'__DIE__'} = sub { my $m = shift; if ($i++ > 4) { - print "# infinite recursion\, bailing\nnot ok 52\n"; + print "# infinite recursion\, bailing\nnot ok 53\n"; exit 1; } print "# $m"; - if ($m =~ /^Modification of a read-only/) { print "ok 52\n" } + if ($m =~ /^Modification of a read-only/) { print "ok 53\n" } }; package C; sub new { bless {}\, shift } @@ -275\,7 +279\,7 @@ print $$_\,"\n";
{ my @a; - $a[1] = "ok 53\n"; + $a[1] = "ok 54\n"; print ${\$_} for @a; }
@@ -283\,9 +287\,9 @@ print $$_\,"\n"; $a = [1\,2\,3]; $a = $a->[1]; print "not " unless $a == 2; -print "ok 54\n"; +print "ok 55\n";
-sub x::DESTROY {print "ok "\, 54 + shift->[0]\, "\n"} +sub x::DESTROY {print "ok "\, 55 + shift->[0]\, "\n"} { my $a1 = bless [4]\,"x"; my $a2 = bless [3]\,"x"; { my $a3 = bless [2]\,"x"; @@ -297\,7 +301\,7 @@ sub x::DESTROY {print "ok "\, 54 + shift-
# test global destruction
-my $test = 59; +my $test = 60; my $test1 = $test + 1; my $test2 = $test + 2;
--- perl-current/t/op/chop.t Thu Jan 4 16:49:42 2001 +++ perl-changed/t/op/chop.t Sat Jan 27 19:19:18 2001 @@ -1\,6 +1\,6 @@ #!./perl
-print "1..33\n"; +print "1..37\n";
# optimized
@@ -103\,3 +103\,14 @@ print $_ eq "abc\x{1234}" ? "ok 32\n" : $_ = "\x{1234}\x{2345}"; chop; print $_ eq "\x{1234}" ? "ok 33\n" : "not ok 33\n"; + +# chop and chomp can't be lvalues +eval 'chop($x) = 1;'; +print $@ =~ /Can\'t modify.*chop.*in.*assignment/ ? "ok 34\n" : "not ok 34\n"; +eval 'chomp($x) = 1;'; +print $@ =~ /Can\'t modify.*chom?p.*in.*assignment/ ? "ok 35\n" : "not ok 35\n"; +eval 'chop($x\, $y) = (1\, 2);'; +print $@ =~ /Can\'t modify.*chop.*in.*assignment/ ? "ok 36\n" : "not ok 36\n"; +eval 'chomp($x\, $y) = (1\, 2);'; +print $@ =~ /Can\'t modify.*chom?p.*in.*assignment/ ? "ok 37\n" : "not ok 37\n"; +
sthoenna@efn.org (Yitzchak Scott-Thoennes) wrote: :Looks like this patch never got applied. In any case 20000808.005 :(now #3661) can be closed.
:On Sat\, 27 Jan 2001 19:31:29 -0800 (PST)\, smcc@CSUA.Berkeley.EDU wrote: [...] :>The following patch fixes the chomp() problem and adds test for both.
Thanks\, applied as #17717.
Hugo
@gbarr - Status changed from 'open' to 'resolved'
Migrated from rt.perl.org#3661 (status was 'resolved')
Searchable as RT3661$