Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

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?

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 all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2017-08-18 06:08 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (294 votes). Check out past polls.