Can someone clear up the syntax of how I pass an object to a subroutine? I tried passing a reference too, and I just can't quite get the syntax right.
As others have noted, an object -- eg $object -- is a reference to something or other, which has been "blessed". So there is no special syntax for passing objects, you just pass the reference just like any other scalar. Most of the time one can forget that $object is not the object, but is one step removed.
Perl's parameter handling is, of course, "interesting". Assuming the usual ($a, $b, ...) = @_ ;, arguments are passed by value. Where the argument is an object, the value that is passed is the reference -- which can lead to disappointment if one forgets that the object itself is not passed by value.
However, what you are doing is deeper than this. You are passing an object from one thread to another.
Each thread has its own, separate address space, which is a copy of the creating thread's address space, taken at the moment of creation. So... although the creation of the thread looks like a subroutine call, it's not quite -- objects, for example, really are passed by value. Consider:
my $o = bless { a => 'A', b => 'B' }, "CLASS" ;
show('main - pre ', $o) ;
my $t = threads->new(\&proc, 'thread', $o) ; $t->join() ;
show('main - post', $o) ;
sub proc {
my ($t, $x) = @_ ;
$$x{z} = 'Z' ;
show($t, $x) ;
} ;
sub show {
my ($t, $x) = @_ ;
printf "%20s: ", $t ;
print "$x {", join(", ", map { "$_ => $$x{$_}" } sort keys %$x), "
+}\n" ;
} ;
which gives:
main - pre : CLASS=HASH(0x15c2e88) {a => A, b => B}
thread: CLASS=HASH(0x1adee98) {a => A, b => B, z => Z}
main - post: CLASS=HASH(0x15c2e88) {a => A, b => B}
On the other hand, if the value of the object is created 'shared', thus:
my %s : shared = ( x => 'X', y => 'Y' ) ;
my $o = bless \%s, "SHARE" ;
we get the usual semantics of passing an object:
main - pre : SHARE=HASH(0x15c4778) {x => X, y => Y}
thread: SHARE=HASH(0x1825950) {x => X, y => Y, z => Z}
main - post: SHARE=HASH(0x15c4778) {x => X, y => Y, z => Z}
Love it ? You bet !
And, just for completeness, returning an object from a thread is fraught... consider:
my $t = threads->new(\&make, a => 'A', b => 'B') ; my $o = $t->join(
+) ;
show('main', $o) ;
sub make {
my %s : shared = @_ ;
my $m : shared = bless \%s, "MADE" ;
show('thread', $m) ;
return $m ;
} ;
use Scalar::Util qw(reftype) ;
sub show {
my ($t, $x) = @_ ;
printf "%20s: %s", $t, $x ;
my $r = reftype($x) || '' ;
if ($r eq 'SCALAR') { print " = ", defined($$x) ? "'$$x'" : 'undef
+' ; } ;
if ($r eq 'ARRAY') { print " = [", join(", ", @$x), "]" ;
+ } ;
if ($r eq 'HASH') { print " = {", join(", ", map { "$_ => $$x{$_
+}" } sort keys %$x), "}" ; } ;
print "\n" ;
} ;
which gives:
thread: MADE=HASH(0x197d4e0) = {a => A, b => B}
main: SCALAR(0x1712078) = undef
and I cannot find a way to make this work -- not even with shared object value and body (as above).
|