modification of a read-only value
David Alban
extasia at extasia.org
Tue Jun 3 03:41:03 BST 2008
greetings,
as a fan of the Readonly module, i've seen and corrected many
situations where i get "Modification of a read-only value attempted".
but i got one today i don't quite grok.
i have a routine ql() that i use often. apparently i first used it on
a Readonly only just today. i seems that Data::Dumper::Dumper() is
doing something to offend Readonly. in my example below, old_ql() is
a boiled down version of my subroutine and new_ql() is the
modification i made to get it to work with Readonly constants. the
program below outputs:
$VAR1 = "\177";
Modification of a read-only value attempted at
/usr/lib/perl5/5.8.5/i386-linux-thread-multi/Data/Dumper.pm line 611
Modification of a read-only value attempted at junk line 0
Here's the test program:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use Readonly;
Readonly::Scalar my $c => chr hex "7f";
print new_ql( $c );
print old_ql( $c );
sub new_ql {
my @args_copy = @_;
"@args_copy" =~ m{ [^[:print:]] }xms and $Data::Dumper::Useqq = 1;
return join( ", ", map { Dumper $_; } @args_copy );
} # new_ql
sub old_ql {
"@_" =~ m{ [^[:print:]] }xms and $Data::Dumper::Useqq = 1;
return join( ", ", map { Dumper $_; } @_ );
} # old_ql
the only difference between the old and new routines is using a copy of @_.
lines near 611 in Dumper.pm are:
608
609 # put a string value in double quotes
610 sub qquote {
611 local($_) = shift;
612 s/([\\\"\@\$])/\\$1/g;
613 my $bytes; { use bytes; $bytes = length }
614 s/([^\x00-\x7f])/'\x{'.sprintf("%x",ord($1)).'}'/ge if
$bytes > length;
615 return qq("$_") unless
616 /[^ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~]/; # fast exit
617
618 my $high = shift || "";
619 s/([\a\b\t\n\f\r\e])/$esc{$1}/g;
620
621 if (ord('^')==94) { # ascii
622 # no need for 3 digits in escape for these
623 s/([\0-\037])(?!\d)/'\\'.sprintf('%o',ord($1))/eg;
624 s/([\0-\037\177])/'\\'.sprintf('%03o',ord($1))/eg;
625 # all but last branch below not supported --BEHAVIOR
SUBJECT TO CHANGE--
626 if ($high eq "iso8859") {
627 s/([\200-\240])/'\\'.sprintf('%o',ord($1))/eg;
628 } elsif ($high eq "utf8") {
629 # use utf8;
630 # $str =~ s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge;
631 } elsif ($high eq "8bit") {
632 # leave it as it is
633 } else {
634 s/([\200-\377])/'\\'.sprintf('%03o',ord($1))/eg;
635 s/([^\040-\176])/sprintf "\\x{%04x}", ord($1)/ge;
636 }
637 }
638 else { # ebcdic
639 s{([^ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~])(?!\d)}
640 {my $v = ord($1); '\\'.sprintf(($v <= 037 ? '%o' :
'%03o'), $v)}eg;
641 s{([^ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~])}
642 {'\\'.sprintf('%03o',ord($1))}eg;
643 }
644
645 return qq("$_");
646 }
i have a simple fix, but i'm curious as to why this is happening. it
seems as though Dumper() should be able to what it needs only reading
the value it's trying to print.
thanks,
david
--
Live in a world of your own, but always welcome visitors.
More information about the london.pm
mailing list