in reply to "Auto" vivifying shared data structures

Here's what I wrote for Object-InsideOut for creating a shared copy of a complex data structure:
# Make a copy of a complex data structure that is thread-shared. # If not thread sharing, then make a 'regular' copy. sub shared_copy { my $in = $_[0]; # Make copies of array, hash and scalar refs if (my $ref_type = ref($in)) { # Copy an array ref if ($ref_type eq 'ARRAY') { # Make empty shared array ref my $out = ($threads::shared::threads_shared) ? &threads::shared::share([]) : []; # Recursively copy and add contents for my $val (@$in) { push(@$out, shared_copy($val)); } return ($out); } # Copy a hash ref if ($ref_type eq 'HASH') { # Make empty shared hash ref my $out = ($threads::shared::threads_shared) ? &threads::shared::share({}) : {}; # Recursively copy and add contents while (my ($key, $val) = each(%$in)) { $out->{$key} = shared_copy($val); } return ($out); } # Copy a scalar ref if ($ref_type eq 'SCALAR') { if ($threads::shared::threads_shared) { return (threads::shared::share($in)); } # If not sharing, then make a copy of the scalar ref my $out = \do{ my $scalar; }; $$out = $$in; return ($out); } } # Just return anything else # NOTE: This will generate an error if we're thread-sharing, # and $in is not an ordinary scalar. return ($in); }
You would use it in your application by first creating a regular version of a data structure, and then running it through this code. The returned shared copy can then be added safely to whatever shared structure you're working with.

If you still find that doesn't work, then you may be bumping up against problems with threads under ActivePerl 5.8.4. See Re^3: New Module Announcement: Object::InsideOut.


Remember: There's always one more bug.

Replies are listed 'Best First'.
Re^2: "Auto" vivifying shared data structures
by Dr. Mu (Hermit) on Nov 17, 2005 at 21:17 UTC
    Well, you've read my mind, apparently. If I couldn't get my in situ routine to work, the next step was going to be to copy a node from the shared hash, do the insertion work on it, then copy it back -- making sure, in the process, that all the subnodes are shared. If I go that route, your routine will come in handy. Thanks!