Scalar::Util::weaken() proposed to use in the conjunction with the CLONE function to solve the problem of cloning non-perl objects suffers itself from cloning. Here is an example: #/tmp/weaken2 package main; use threads; use Scalar::Util; my $data = "a"; my $obj = \$data; my $copy = $obj; Scalar::Util::weaken($copy); threads->new(sub { print "thread started\n";})->detach for (1..1); sleep 1; % perl-5.8.1-ithread /tmp/weaken2 thread started Attempt to free unreferenced scalar SV 0x8154f74. Oops, a weakened $copy was cloned too, but its guts are now messed up. What scalar do you ask is unreferenced? It's the magic that was added by weaken() and cloned during perl_clone, that perl complains about. Here is a more complex program that proves that with Devel::Peek: #/tmp/weaken package Foo; use strict; use warnings; use Scalar::Util; use Devel::Peek; my %objects; sub new { my $data = "a"; my $self = bless \$data, __PACKAGE__; my $copy = $self; Scalar::Util::weaken($copy); $objects{"$self"} = $copy; return $self; } sub DESTROY { warn "DESTROY\n"; } sub CLONE { warn "CLONE is called"; for my $key ( keys %objects) { my $self = delete $objects{$key}; Dump $self; } } package main; use threads; my $obj = Foo->new; threads->new(sub { print "thread started\n";})->detach for (1..1); sleep 1; % perl-5.8.1-ithread /tmp/weaken CLONE is called at /tmp/weaken line 23. SV = RV(0x8110b2c) at 0x815de1c REFCNT = 1 FLAGS = (PADBUSY,PADMY,ROK) RV = 0x8156e1c SV = PVMG(0x8115e38) at 0x8156e1c REFCNT = 2 FLAGS = (PADBUSY,PADMY,OBJECT,RMG,POK,pPOK) IV = 0 NV = 0 PV = 0x8157860 "a"\0 CUR = 1 LEN = 2 MAGIC = 0x8157828 MG_VIRTUAL = &PL_vtbl_backref MG_TYPE = PERL_MAGIC_backref(<) MG_FLAGS = 0x02 REFCOUNTED MG_OBJ = 0x8156e28 SV = PVAV(0x8153494) at 0x8156e28 REFCNT = 1 FLAGS = () IV = 0 NV = 0 ARRAY = 0x8157848 FILL = 0 MAX = 3 ARYLEN = 0x0 FLAGS = (REAL) Elt No. 0 STASH = 0x8156d2c "Foo" thread started DESTROY Attempt to free unreferenced scalar SV 0x8156e28 during global destruction. DESTROY As you can see SV 0x8156e28 is: SV = PVAV(0x8153494) at 0x8156e28 REFCNT = 1 FLAGS = () IV = 0 NV = 0 ARRAY = 0x8157848 FILL = 0 MAX = 3 ARYLEN = 0x0 FLAGS = (REAL) Elt No. 0 Any chance we can change perl to call Devel::Peek::Dump when producing: Attempt to free unreferenced scalar SV 0x8154f74. would save us a lot of time, trying to figure out what SV went lost. __________________________________________________________________ Stas Bekman JAm_pH ------> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:stas@stason.org http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.comThread Previous | Thread Next