Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

%+ and cloning

by PetaMem (Priest)
on Jan 11, 2010 at 11:01 UTC ( #816700=perlquestion: print w/ replies, xml ) Need Help??
PetaMem has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, it seems, that %+ refuses regular attempts of cloning it:
#!/usr/bin/perl use strict; use warnings; use Storable qw(dclone); use Data::Dumper; my $str = "Rico"; $str =~ m{(?<name>ico)}xms; my $match = dclone \%+; print \%+,"\n"; print "match: $match\n", Dumper($match); $str =~ m{(?<buba>R)}xms; my $match2 = dclone \%+; print \%+,"\n"; print "match: $match\n", Dumper($match); print "match2: $match2\n", Dumper($match2);

edit:

output on my machine:

HASH(0x1c6fba0)
match:  HASH(0x1a20d48)
$VAR1 = {
          'name' => 'ico'
        };
HASH(0x1c6fba0)
match:  HASH(0x1a20d48)
$VAR1 = {
          'buba' => 'R'  # <- now this is unexpected
        };
match2: HASH(0x1a4baf0)
$VAR1 = {
          'buba' => 'R'
        };
In contrast, the following code works as expected:
my %test = ( hula => 1, ); my $testclone = dclone \%test; print "test: $testclone\n", Dumper($testclone); %test = ( different => 1, ); my $testclone2 = dclone \%test; print "test: $testclone\n", Dumper($testclone); print "test2: $testclone2\n", Dumper($testclone2);

What's going on here? The cloned hashref ($match) changes content although it has (and keeps) a different address.

$ perl -V Summary of my perl5 (revision 5 version 10 subversion 1) configuration +: Platform: osname=linux, osvers=2.6.30-tuxonice-r5, archname=x86_64-linux-thr +ead-multi uname='linux sol 2.6.30-tuxonice-r5 #1 smp preempt tue sep 1 15:41 +:45 cest 2009 x86_64 intel(r) core(tm)2 cpu t7200 @ 2.00ghz genuinein +tel gnulinux ' config_args='-des -Duseshrplib -Darchname=x86_64-linux-thread -Dcc +=x86_64-pc-linux-gnu-gcc -Doptimize=-march=core2 -O2 -pipe -Dscriptdi +r=/usr/bin -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr -Dprivlib=/usr +/lib64/perl5/5.10.1 -Darchlib=/usr/lib64/perl5/5.10.1/x86_64-linux-th +read-multi -Dvendorlib=/usr/lib64/perl5/vendor_perl/5.10.1 -Dvendorarch=/usr/ +lib64/perl5/vendor_perl/5.10.1/x86_64-linux-thread-multi -Dsitelib=/usr/lib64/perl5/site_perl/5.10.1 -Dsitearch=/usr/lib64/ +perl5/site_perl/5.10.1/x86_64-linux-thread-multi -Dlibperl=libperl.so.5.10.1 -Dlocincpth= -Duselargefiles -Dd_semc +tl_semun -Dinc_version_list=5.10.0 5.10.0/x86_64-linux-thread-multi - +Dcf_by=Gentoo -Dmyhostname=localhost -Dperladmin=root@localhost -Dinstallusrbinperl=n -Ud_csh -Uusenm -Dusethreads -Ui_ndbm -Ui_gdb +m -Ui_db -Dusrinc=/usr/include -Dlibpth=/usr/local/lib64 /lib64 /usr/ +lib64' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=und +ef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef

Bye
 PetaMem
    All Perl:   MT, NLP, NLU

Comment on %+ and cloning
Select or Download Code
Re: %+ and cloning
by JavaFan (Canon) on Jan 11, 2010 at 11:48 UTC
    Please, please, please, if you're going to post code fragments to show differences of behaviour SHOW THE OUTPUT! - don't expect people who're going to help you copy the work you've done.

    Now, I'm just going to guess what's happening: %+ is actually a tied array, and dclone copies the tie magic.

Re: %+ and cloning
by BrowserUk (Pope) on Jan 11, 2010 at 12:03 UTC

    Try this version of your code that uses Data::Dump and things become obvious:

    #! perl -slw use strict; use warnings; use Storable qw(dclone); use Data::Dump qw[ pp ]; my $str = "Rico"; $str =~ m{(?<name>ico)}xms; my $match = dclone \%+; print \%+,; print " match: $match -", pp $match; $str =~ m{(?<buba>R)}xms; my $match2 = dclone \%+; print \%+; print " match: $match ", pp $match; print "match2: $match2 ", pp $match2; __END__ C:\test>816700 HASH(0x22ee20) match: HASH(0x6f218) -{ # tied Tie::Hash::NamedCapture } HASH(0x22ee20) match: HASH(0x6f218) { # tied Tie::Hash::NamedCapture } match2: HASH(0x6f128) { # tied Tie::Hash::NamedCapture }

    %+ is not a real hash, but rather a tied hash. And cloning it appears to simply gives you another tied reference to the same global internal data structure.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Thanks for your insight.

      So I went back to twig technology and copied the hash via
      sub copy_hash { my $hr = shift // return {}; # get hash to copy or return empty ha +shref if not given my %copy = (); while (my ($k, $v) = each %{$hr}) { $copy{$k} = $v; } return \%copy; }

      Which works. So this is it? Best way to go?

      Bye
       PetaMem
          All Perl:   MT, NLP, NLU

        That depends on ones definition of 'best'. One could also write:
        sub copy_hash { my $hr = shift // return {}; my $copy; @$copy{keys %$hr} = value %$hr; $copy; }
        or just:
        sub copy_hash {{%{$_[0]//{}}}}
        Or without a sub:
        my %copy = %+;

        A simple my %copy = %+; is equivalent to your sub. However, that may not be enough!

        According to the docs for Tie::Hash::NamedCapture, the values of the tied hash can contain an array reference holding multiple captures due to the re-use of the same named capture. In which case you might need to use something more complex to perform a deep copy operation.

        That said, in my simple tests, this doesn't seem to apply to %+. It does apply to %- though.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (9)
As of 2014-12-21 07:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (104 votes), past polls