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

Is there any direct way to test if a variable is threads::shared ? I can't find anything in the threads::shared docs, nor in perlthrtut, nor in a Google search, nor in a search here. Currently, my only solution is this bit of code:
sub shared_test { my $var_ref = shift; return undef unless ref $var_ref; my $safety : shared; eval { $safety = $var_ref; }; return !$@; } my $shared : shared = 1; my $private = 2; shared_test(\$shared); shared_test(\$private);
...which is a pretty expensive operation for something which should be a simple test. Any help much appreciated.

Replies are listed 'Best First'.
Re: Testing if variable is threads::shared ?
by jdhedden (Deacon) on Aug 30, 2005 at 18:32 UTC
    Use threads::shared::_id(\$var), as in:
    use threads; use threads::shared; my $var : shared; if (threads::shared::_id($var)) { print("'\$var' is shared\n"); }
    It returns a true value (a memory address) if $var is shared, and undef if not.

    NOTE: This is not documented, and the underscore in the name indicates its internal use nature. This function is found in ext/threads/shared/shared.xs in the Perl source code distribution.

    UPDATE: Corrected as per below. Thanks pg.


    Remember: There's always one more bug.

      The posted code returned:

      Undefined subroutine &threads::shared::_id called at math1.pl line 5.

      Testing is done with 5.8.4 on windows XP.

      Update: The above code could be fixed like this:

      use threads; #added use threads::shared; my $var : shared; if (threads::shared::_id($var)) {#pass the var not the ref print("'\$var' is shared\n"); }
      Groovy! Many thanks.

      Couple of things:

      1) Any chance this will be exported into a public method someday ?

      2) FYI: When I tried directly testing a ref operator (e.g., threads::shared::_id(\@ary)), it choked. I had to explicitly assign the ref to another variable, then it reports shared (which is the important bit for me).

      For the record, here's a bit more complete test:

      use threads; use threads::shared; package Dweeble; sub new { my $class = shift; my %obj : shared = ( cow => 'bossy' ); return bless \%obj, $class; } sub holycow { print "Holy Cow!\n"; } 1; package main; my $hope : shared = 27; my @ary : shared = (1,2,3,4,5); my $aryref = \@ary; my %hash : shared = ( one => 1, two => 2 ); my $hashref = \%hash; my $cow; my $krelboin = Dweeble->new(); print "hope is ", (threads::shared::_id($hope) ? "shared\n" : "private +\n"); print "cow is ", (threads::shared::_id($cow) ? "shared\n" : "private\n +"); print "ary is ", (threads::shared::_id($aryref) ? "shared\n" : "privat +e\n"); print "hash is ", (threads::shared::_id($hashref) ? "shared\n" : "priv +ate\n"); print "krelboin is ", (threads::shared::_id($krelboin) ? "shared\n" : +"private\n");
        1) Any chance this will be exported into a public method someday?
        Most likely not. However, it probably isn't going to go away either. It's still in the blead code.

        Remember: There's always one more bug.