llancet has asked for the wisdom of the Perl Monks concerning the following question:

I want to use Moose system in a project that requires threaded programming, and share object between threads. So I attempted to create an object that is shared, using Moose's "BUILD" mechanism. And I hope that any classes extending this one will be automatically sharing-friendly classes.
use strict; use threads; use threads::shared; { package ThreadableObj; use Moose; use threads::shared; use Data::Dump qw/dump/; sub BUILD { my $self = shift; # here the blessed() already be the version in threads::shared bless shared_clone($self), ref($self); print dump($self),"\n"; return $self; } has foo => ( is => 'rw', isa => 'Str' ); has bar => ( is => 'rw', isa => 'Int' ) } # here dies my $obj : shared = ThreadableObj->new(foo=>'foovalue');
However, the constructed object is not shared, as shows in this error message:
Invalid value for shared scalar at XXXXX
Moreover, the output of dump() is:
bless({ bar => 123, foo => "foovalue" }, "ThreadableObj")
Any suggestions? Thanks a lot!

Replies are listed 'Best First'.
Re: Attempt to make shared Moose object
by tigre (Acolyte) on Mar 01, 2010 at 19:41 UTC

    A few things:

    1. "shared_clone" returns a new object, and your code does not store that value anywhere.
    2. BUILD does not change the value returned by 'new'. I think you need to use an "around" modifier for "new".
    3. I don't see any reason bar would have a value except that you must have left some code out of the example somewhere.

    To sum up:

    use threads; use strict; { package ThreadableObj; use Moose; use threads::shared; use Data::Dumper; around 'new' => sub { my $orig = shift; my $class = shift; my $self = $class->$orig(@_); my $shared_self : shared = shared_clone($self); # here the blessed() already be the version in threads::shared print Dumper($shared_self),"\n"; return $shared_self; }; has foo => ( is => 'rw', isa => 'Str' ); has bar => ( is => 'rw', isa => 'Int' ); } # here lives my $obj : shared = ThreadableObj->new(foo=>'foovalue');
      Thanks a lot!
      (delete faulse reply)