Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Readonly problems

by runrig (Abbot)
on Dec 17, 2013 at 01:00 UTC ( #1067402=perlquestion: print w/ replies, xml ) Need Help??
runrig has asked for the wisdom of the Perl Monks concerning the following question:

I'm wondering about the behaviour of the following:
use Scalar::Util qw(readonly);; my %hash = ( A => 1 ); while ( my ( $abc, $num ) = each %hash ) { print "$abc\n"; print "$abc is readonly\n" if readonly($abc); my $bar = $abc; print "bar is readonly\n" if readonly($bar); foo($abc); print "$abc is still readonly\n" if readonly($abc); } sub foo { $_[0] .= 'FOO'; }
This prints (on perl 5.14.1):
A A is readonly bar is readonly
First, I don't expect $abc to be read-only, as it is not an alias for the hash key, but if it is readonly, then the call to foo() should not work, we should get a "modification of a readonly value" error. And why is $bar read-only? It's just a copy of the value in $abc. Or has this changed in recent versions of perl?

Comment on Readonly problems
Select or Download Code
Replies are listed 'Best First'.
Re: Readonly problems (Devel::Peek, Scalar::Util::readonly bug)
by Anonymous Monk on Dec 17, 2013 at 01:21 UTC
    hash keys are read-only but they're not really readonly ... so Scalar::Util::readonly has bug in that it doesn't document the nuances of readonlyness :)
    #!/usr/bin/perl -- use strict; use warnings; use Devel::Peek qw/ Dump /; use Readonly; Readonly::Scalar my $rs => 66; my %hh = qw/ A B /; while( my( $k, $v ) = each %hh ){ Dump( $k ); Dump( $v ); } for( 1 ){ Dump( $_ ); ## the readonliest } Dump( $rs ); __END__
    SV = PV(0x3f7b44) at 0x99b8ac
      REFCNT = 1
      PV = 0x99ce88 "A"
      CUR = 1
      LEN = 0
    SV = PV(0x3f7b4c) at 0xaca8bc
      REFCNT = 1
      PV = 0xadf504 "B"\0
      CUR = 1
      LEN = 12
    SV = IV(0xae0670) at 0xae0674
      REFCNT = 2
      IV = 1
    SV = PVMG(0xad50e4) at 0x3f9bac
      REFCNT = 1
      IV = 0
      NV = 0
      PV = 0
      MAGIC = 0x99402c
        MG_VIRTUAL = &PL_vtbl_packelem
        MG_TYPE = PERL_MAGIC_tiedscalar(q)
        MG_FLAGS = 0x02
        MG_OBJ = 0x3f9adc
        SV = IV(0x3f9ad8) at 0x3f9adc
          REFCNT = 1
          FLAGS = (ROK)
          RV = 0xad353c
          SV = PVMG(0xad50c4) at 0xad353c
            REFCNT = 1
            IV = 66
            NV = 0
            PV = 0
            STASH = 0xacab0c        "Readonly::Scalar"

    Oh, and is unreadable ..., redefining Internals::SvREADONLY

        Thanks, I don't really want to use readonly() though, I was just tracking down a bug involving DBI/DBD::Oracle. I tracked it down to code that went something like:
        my $data = {}; my $sth = $dbh->prepare($sql); $sth->bind_param_inout(':foo' => \$data->{foo}, 10); while ( my ($k, $v) = each %hash ) { $data->{foo} = $k; $sth->execute(); }
        And I got a 'modification of readonly value' error on the execute. Workaround is to modify the 'readonly' value before the execute with something like:
        $k .= '';
        Update: And for now, that whole thing needs a reset every few iterations, as execute() leaks memory with inout parameters.

        Update2: And the previously mentioned 'leak' has been fixed in the latest release.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1067402]
Approved by GrandFather
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2015-09-01 21:53 GMT
Find Nodes?
    Voting Booth?

    My preferred temperature scale is:

    Results (50 votes), past polls