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

Hello again :-)

Hopefully this is a simple problem ... I'd like some help getting this second method to work.

I am working with a class that contains the following method:

# Adds fields to a shared object sub set { my ($self, $tag, $value) = @_; lock($self); $self->{$tag} = shared_clone($value); }

I'm trying to add a second method similar to the first:

# Adds sub fields to a shared object sub set_alwd_info { my ($self, $tag, $value) = @_; lock($self); 43: $self->{ALWD_INFO}{$tag} = shared_clone($value); }

But I'm getting this error when I try to run it:

Invalid value for shared scalar at ./thread line 32.

Full sample code:

#!/usr/bin/perl # package ALWD::Cows; use strict; use warnings; use threads; use threads::shared qw(share is_shared shared_clone); # Constructor sub new { my $class = shift; share(my %self); # $self{ALWD_INFO} = {}; # ... ... ... my $self = bless(\%self, $class); return $self; } # Adds fields to a shared object sub set { my ($self, $tag, $value) = @_; lock($self); $self->{$tag} = shared_clone($value); } # Adds sub fields to a shared object sub set_alwd_info { my ($self, $tag, $value) = @_; lock($self); $self->{ALWD_INFO}{$tag} = shared_clone($value); } package main; my $sample = ALWD::Cows->new(); $sample->set("Key1", "Value1"); $sample->set_alwd_info("Key2", "Value2");

Replies are listed 'Best First'.
Re: Invalid value for shared scalar
by BrowserUk (Patriarch) on Feb 03, 2016 at 19:56 UTC

    Here you're adding a key and scalar value to an existing shared hash:

    $self->{$tag} = shared_clone($value);

    Whereas here, you are attempting to autovivify an anonymous hash containing that key/value pair and assign a reference to it as the value of the key "ALWD_INFO" in the shared hash:

    $self->{ALWD_INFO}{$tag} = shared_clone($value);

    That reference to an unshared anonymous hash is an invalid value for a shared scalar.

    Simple fix:

    sub set_alwd_info { my ($self, $tag, $value) = @_; my %temp : shared = ( $tag => $value ); lock($self); $self->{ALWD_INFO} = \%temp; }

    Update: However, if the sub will be called multiple times, with different key/value pairs and you want them to accumulate, then you'll only want to vivify the nested shared hash once:

    sub set_alwd_info { my ($self, $tag, $value) = @_; if( not exists $self->{ALWD_INFO} or ref( $self->{ALWD_INFO} ) ne +'HASH' ) { my %temp : shared = ( $tag => shared_clone($value) ); lock($self); $self->{ALWD_INFO} = \%temp; } else { $self->{ALWD_INFO}{$tag} = shared_clone($value); } }

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Invalid value for shared scalar
by SwaJime (Scribe) on Feb 03, 2016 at 20:49 UTC

    I appreciate the help. I actually found a one line fix while waiting for an answer.

    Adding this line above return $self; fixed the problem:
    $self->{ALWD_INFO} = shared_clone({});
Re: Invalid value for shared scalar
by poj (Abbot) on Feb 03, 2016 at 20:14 UTC

    What happens if you do 2 method calls ?

    $sample->set_alwd_info("Key2", "Value2"); $sample->set_alwd_info("Key3", "Value3");
    poj