Jenda has asked for the wisdom of the Perl Monks concerning the following question:
I wanted to use Scalar::Util::readonly() to help distinguish between foo( 1,2,3) and foo( -one => 1, -two => 2, -three => 3), but it looks like there is an error (or at least an unexpected behaviour) in Perl. At least in my version. If I call foo( named => 1) then $_[0] is readonly, if I call foo( -named => 1), it's not.
use strict; use Carp; use Scalar::Util qw(readonly); sub ro { print "readonly($_[0])=".readonly($_[0])."\n"; $_[0] = 'xxx'; } eval { ro('lonely') } or print $@; eval { ro(named => 4); } or print $@; eval { ro(-named => 7); } or print $@; for (1..5) { # to test whether changing $_[0] affects the literal eval { ro(-loop => 7); } or print $@; }
I guess the
explains it ... I expected the -foo => 1 to be parsed as (or optimized to) '-foo' => 1, but it looks like its not. What do you get with your version of perl?V:\>perl -MO=Deparse -e "%a = (-foo => 1);" (%a) = (-'foo', 1); -e syntax OK
Update: There seems to be a speed difference as well:
use strict; use Benchmark; sub woH { my %a = ( -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, + -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => + 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a + => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, + -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => + 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a + => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, + -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => + 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a + => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, + -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => + 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a + => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, + -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => + 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a => 1, -a + => 1, ); return; } sub wH { my %a = ( '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => + 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, + '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '- +a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => + 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, + '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '- +a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => + 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, + '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '- +a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => + 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, + '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '- +a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => + 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, + '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '- +a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, '-a' => 1, ); return; } timethese 100000, { woH => \&woH, wH => \&wH, } __END__ Benchmark: timing 100000 iterations of wH, woH... wH: 1 wallclock secs ( 1.45 usr + 0.00 sys = 1.45 CPU) @ 68 +917.99/s (n=100000) woH: 3 wallclock secs ( 2.39 usr + 0.00 sys = 2.39 CPU) @ 41 +893.59/s (n=100000) Benchmark: timing 100000 iterations of wH, woH... wH: 2 wallclock secs ( 1.47 usr + 0.01 sys = 1.48 CPU) @ 67 +521.94/s (n=100000) woH: 2 wallclock secs ( 2.32 usr + 0.02 sys = 2.34 CPU) @ 42 +735.04/s (n=100000) Benchmark: timing 100000 iterations of wH, woH... wH: 1 wallclock secs ( 1.42 usr + 0.00 sys = 1.42 CPU) @ 70 +472.16/s (n=100000) woH: 3 wallclock secs ( 2.56 usr + 0.00 sys = 2.56 CPU) @ 39 +077.76/s (n=100000)
Another strange thing:
D:\>perl -MO=Deparse -e "print -'ahoj' => 1" print '-ahoj', 1; -e syntax OK D:\>perl -MO=Deparse -e "print -ahoj => 1" print -'ahoj', 1; -e syntax OK
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: -foo not readonly in fun(-foo => 1} in perl v5.8.7
by elmex (Friar) on Apr 19, 2008 at 17:02 UTC | |
by apl (Monsignor) on Apr 20, 2008 at 13:29 UTC | |
|
Re: -foo not readonly in fun(-foo => 1} in perl v5.8.7 (wishes)
by tye (Sage) on Apr 20, 2008 at 03:57 UTC | |
by Jenda (Abbot) on Apr 20, 2008 at 08:23 UTC |