Re: foreach funny business
by Sidhekin (Priest) on Jun 29, 2006 at 19:35 UTC
|
A bug in your version of perl, perhaps? On mine, it dies:
sidhekin@blackbox:~$ perl -v
This is perl, v5.8.7 built for i486-linux
Copyright 1987-2005, Larry Wall
Perl may be copied only under the terms of either the Artistic License
+ or the
GNU General Public License, which may be found in the Perl 5 source ki
+t.
Complete documentation for Perl, including FAQ lists, should be found
+on
this system using `man perl' or `perldoc perl'. If you have access to
+ the
Internet, point your browser at http://www.perl.org/, the Perl Home Pa
+ge.
sidhekin@blackbox:~$ perl
sub mychop(\$) { chop ${shift()} }
foreach my $thing (qw/foo bar baz/) {
print "$thing -> ";
my $c = mychop $thing;
print " $thing,$c\n";
}
__END__
Modification of a read-only value attempted at - line 1.
foo ->
Update: After some trial-and-error, it seems to be the case that, on threaded builds, trying to take a reference to an alias of a constant string creates a copy of that constant string and results in a reference to that copy, while on non-threaded builds, you get a reference to the constant itself.
# v5.8.3 built for i386-linux-thread-multi:
-bash-2.05b$ perl -le 'print map{chop$$_, $_}\$_, \$_, \$_ for "abc",
+($x="abc")'
cSCALAR(0x804cbb8)cSCALAR(0x804cc78)cSCALAR(0x804c99c)
cSCALAR(0x805f69c)bSCALAR(0x805f69c)aSCALAR(0x805f69c)
# v5.8.7 built for i486-linux:
sidhekin@blackbox:~$ perl -le 'print map{chop$$_, $_}\$_, \$_, \$_ for
+ "abc", ($x="abc")'
Modification of a read-only value attempted at -e line 1.
Attempt to free unreferenced scalar: SV 0x812ec2c.
Whether this is a bug or undefined behaviour, though ... I'll leave that for others to decide.
print "Just another Perl ${\(trickster and hacker)},"
The Sidhekin proves Sidhe did it!
| [reply] [d/l] [select] |
|
|
Bug or undefined behaviour? FWIW ive seen this issue with DDS in all kinds of places. It seems to be OS and version dependent. The question comes down to whether shift returns an alias to the item shifted out or if it returns a copy. Similar is whether \\$foo returns a reference to a readonly value or not.
Personally i think that the "reasonable" behaviour is to return a copy as that is the most DWIM behaviour.
---
$world=~s/war/peace/g
| [reply] |
|
|
Interesting. I'm running debian unstable, which has this perl right now:
rob@toblerone:~$ perl -v
This is perl, v5.8.8 built for i486-linux-gnu-thread-multi
Copyright 1987-2006, Larry Wall
etc, etc....
| [reply] [d/l] |
Re: foreach funny business
by Hue-Bond (Priest) on Jun 30, 2006 at 00:16 UTC
|
I just took the time to do some testing on several machines. All these accepted to modify the value:
$ perl -le'sub mychop(\$) { chop ${shift()} } print mychop $_ foreach
+(qw/foo/);'
o
$ perl -le'sub mychop(\$) { chop ${$_[0]} } print mychop $_ foreach (q
+w/foo/);'
o
This is perl, version 5.005_02 built for PA-RISC1.1 - HP-UX td192 B.11
+.11
This is perl, v5.8.3 built for i586-linux-thread-multi - SUSE LINUX En
+terprise Server 9
This is perl, v5.8.3 built for IA64.ARCHREV_0-thread-multi - HP-UX td1
+64 B.11.23
This is perl, v5.8.3 built for x86_64-linux-thread-multi - SUSE LINUX
+Enterprise Server 9
This is perl, v5.8.4 built for alpha-linux-thread-multi - Debian/Linux
+ 3.1
This is perl, v5.8.4 built for i386-linux-thread-multi - Debian/Linux
+3.1
This is perl, v5.8.5 built for i386-linux-thread-multi - Red Hat Enter
+prise Linux AS release 4
This is perl, v5.8.5 built for x86_64-linux-thread-multi - Red Hat Ent
+erprise Linux AS release 4
This is perl, v5.8.8 built for hppa-linux-gnu-thread-multi - Debian/Li
+nux 3.1
While these refused to:
> perl -le'sub mychop(\$) { chop ${shift()} } print mychop $_ foreach
+(qw/foo/);'
Modification of a read-only value attempted at -e line 1.
> perl -le'sub mychop(\$) { chop ${$_[0]} } print mychop $_ foreach (q
+w/foo/);'
Modification of a read-only value attempted at -e line 1.
This is perl, v5.8.0 built for alpha-dec_osf - Compaq Tru64 UNIX V5.1B
This is perl, v5.8.0 built for i386-netbsd - NetBSD 3.0
This is perl, v5.8.6 built for alpha-freebsd - FreeBSD 6.0-RELEASE
This is perl, v5.8.6 built for i386-freebsd-64int - FreeBSD 5.4-RELEAS
+E
Update: I added the operating system by hand, it's not part of the perl -v output on any system.
| [reply] [d/l] [select] |
Re: foreach funny business
by shmem (Chancellor) on Jun 29, 2006 at 19:57 UTC
|
#1
sub mychop(\$) { chop ${shift()} }
versus
# 2
sub mychop(\$) { chop ${$_[0]} }
As perl v5.8.8, the program dies with mychop version #2, but not with version #1.
${shift()} copies (via shift()) $_[0] into a ref-thingy, which is then dereferenced with $ - a behaviour which I deem correct. I would take a die() with #1 as a bug. At version #2 the die() is ok - the reference $_[0] is wrapped into a reference and dereferenced - still $_[0], thus read-only.
mhm.. really? oh, wait...
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] [select] |
|
|
Running your #2 on my perl does not die, and mine claims to be 5.8.8. Are you sure you're on your rocker? :-)
Anyway, to my way of thinking the shift() shouldn't be giving you anything other than _exactly_ what was in $_[0], not some copy.
Now who's with me? /me hoists pitchfork and torch
| [reply] |
|
|
I'm with you, you're right, I'm not. And then, again you're right - 5.8.8 doesn't die, I copied from the wrong shell, and shift() should just pass $_[0], not a copy, unless somebody made shift ro-aware. Have to look after this...
Mhm. Scanning perldelta... nothing. Then, it's a bug. Or it's just undefined behaviour?
But hey, it's a clever one. It's like, say, putting your hand in the band-saw, and get a finger cut, but then you draw out your hand and it's ok because it's read-only. One finger extra ;-)
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] |
Re: foreach funny business
by ikegami (Patriarch) on Jun 29, 2006 at 20:32 UTC
|
Creating a reference to a constant must make a copy of it, because the following works without error too: (Perl v5.6.1)
foreach my $thing (qw/foo bar baz/) {
print "$thing -> ";
my $c = chop ${\$thing};
print " $thing,$c\n";
}
| [reply] [d/l] |
|
|
perseus [gm] 22:26 /home/gm > perl -v
This is perl, v5.6.1 built for i386-openbsd
Copyright 1987-2001, Larry Wall
Perl may be copied only under the terms of either the Artistic License
+ or the
GNU General Public License, which may be found in the Perl 5 source ki
+t.
Complete documentation for Perl, including FAQ lists, should be found
+on
this system using `man perl' or `perldoc perl'. If you have access to
+ the
Internet, point your browser at http://www.perl.com/, the Perl Home Pa
+ge.
perseus [gm] 22:26 /home/gm > perl
foreach my $thing (qw/foo bar baz/) {
print "$thing -> ";
my $c = chop ${\$thing};
print " $thing,$c\n";
}
Modification of a read-only value attempted at - line 3.
foo -> perseus [gm] 22:26 /home/gm >
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
| [reply] [d/l] |
|
|
sidhekin@blackbox:~$ perl
foreach my $thing (qw/foo bar baz/) {
print "$thing -> ";
my $c = chop ${\$thing};
print " $thing,$c\n";
}
__END__
Modification of a read-only value attempted at - line 3.
foo ->
print "Just another Perl ${\(trickster and hacker)},"
The Sidhekin proves Sidhe did it!
| [reply] [d/l] [select] |
|
|
On a debian stable machine I have, I see that that code (${\$thing}) on v5.8.4 built for i386-linux-thread-multi does not die, produces the usual
foo -> foo,o
bar -> bar,r
baz -> baz,z
So, um, there's another data point. | [reply] [d/l] [select] |
Re: foreach funny business
by jwkrahn (Abbot) on Jun 29, 2006 at 19:51 UTC
|
In mychop shift() gives you a copy of the string which you can modify.
| [reply] |
|
|
In mychop shift() gives you a copy of the string which you can modify.
Nope, thanks to the prototype (\$), shift() gives you a copy of a reference to the string, which (when derefed), you really should not be able to modify.
print "Just another Perl ${\(trickster and hacker)},"
The Sidhekin proves Sidhe did it!
| [reply] [d/l] [select] |
Re: foreach funny business
by girarde (Hermit) on Jun 30, 2006 at 03:42 UTC
|
| [reply] |
|
|
They're not barewords. (It's a literal.) He knows why they are not chopable. (It's because they are read-only SVs.) He wants to know why mychop can chop those read-only SVs when chop can't. (Turns out it's pretty random how mychop works on different platforms, so there's probably no good answer to the question.)
| [reply] [d/l] [select] |