Skip Menu |

This queue is for tickets about the threads-shared CPAN distribution.

Report information
The Basics
Id: 97629
Status: resolved
Priority: 0/
Queue: threads-shared

People
Owner: Nobody in particular
Requestors: chris [...] indosoft.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: 1.51



Subject: shared_clone doesn't replicate blessed circular references properly
Date: Wed, 30 Jul 2014 15:52:08 -0300
To: bug-threads-shared [...] rt.cpan.org
From: Chris Orser <chris [...] indosoft.com>
Module version: 1.49 Perl version: v5.18.2 provided by Ubuntu 14.04 I've found that if you create a circular reference before blessing the reference the 'child' reference isn't blessed, even though both references correctly point to the same data. Minimally you can demonstrate the issue with the following: use threads; use threads::shared; my $share = &share({}); my $child = $share; $share->{test} = $child; bless( $share, 'foo' ); print $share, " ", $share->{test}, "\n"; print "Intermediate variable ", $child, "\n"; Output: foo=HASH(0x7ca1b8) HASH(0x7ca1a0) Intermediate variable foo=HASH(0x7ca1b8) The intermediate value does reflect the expected type and also points to the same shared data. The same can be demonstrated using shared_clone: use threads; use threads::shared; my $hash = {}; $hash->{test} = $hash; bless($hash, 'foo'); print $hash, " ", $hash->{test}, "\n"; my $shared = shared_clone($hash); print $shared, " ", $shared->{test}, "\n"; Output: foo=HASH(0x25b9cb8) foo=HASH(0x25b9cb8) foo=HASH(0x25d75d0) HASH(0x25d75b8) I've found that blessing the reference before placing the reference into the $clone cache and then performing the deep copy corrects the problem.
Thanks for pointing this out. I will add the following to the "BUGS AND LIMITATIONS" section of the POD for the next release: --- Blessing a shared item after it has been nested in another shared item does not propagate the blessing to the shared reference: my $foo = &share({}); my $bar = &share({}); $bar->{foo} = $foo; bless($foo, 'baz'); # $foo is now of class 'baz', # but $bar->{foo} is unblessed. Therefore, you should bless objects before sharing them. ---