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
In reply to -foo not readonly in fun(-foo => 1) in perl v5.8.7 by Jenda
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |