I was trying to do some threaded computations and ran into a problem (keys in my shared hash become mysteriously undefined) when one of the subroutines that I called localized $_. If I change the subroutine to use a my variable, everything works fine. I was wondering whether this sort of behavior should have been expected or not.

Here is the simplified code that I'm using. The only interesting thing that happens is in the second to last line of code where I set $$x{foo}. If I use doit_local then $$x{path} becomes an undefined value, however if I use doit_my, $$x{path} retains its proper value.

#!/usr/bin/perl use 5.008; use strict; use warnings; use threads; use threads::shared; use Data::Dumper; my %p1 :shared; my %p2 :shared; %p1 = (path => shift); %p2 = (path => shift); my @t; push @t, threads->create(\&get_md5sums, \%p1); push @t, threads->create(\&get_md5sums, \%p2); $t[0]->join; $t[1]->join; print Dumper \%p1, \%p2; sub doit_local { local $_ = shift; s/'/'\''/g; return $_; } sub doit_my { my $x = shift; $x =~ s/'/'\''/g; return $x; } sub get_md5sums { my $x = shift; print Dumper [$x, $$x{path}]; $$x{foo} = join " ", map '"'.doit_local($_).'"', 'find', $$x{path}, +qw/-type f -exec md5sum {} ;/; return 1; }

Here is the output when I use doit_my. This is the desired output

[duelafn@jhegaala tmp]$ ./local_threads foo bar $VAR1 = [ { 'path' => 'foo' }, 'foo' ]; $VAR1 = [ { 'path' => 'bar' }, 'bar' ]; $VAR1 = { 'path' => 'foo', 'foo' => '"find" "foo" "-type" "f" "-exec" "md5sum" "{}" ";" +' }; $VAR2 = { 'path' => 'bar', 'foo' => '"find" "bar" "-type" "f" "-exec" "md5sum" "{}" ";" +' };

And this is what I get when I use doit_local. Before localizing $_ the shared hash has its correct values, however afterward, the path key is undefined.

[duelafn@jhegaala tmp]$ ./local_threads foo bar $VAR1 = [ { 'path' => 'foo' }, 'foo' ]; Use of uninitialized value in substitution (s///) at ./local_threads l +ine 25. Use of uninitialized value in concatenation (.) or string at ./local_t +hreads line 38. $VAR1 = [ { 'path' => 'bar' }, 'bar' ]; Use of uninitialized value in substitution (s///) at ./local_threads l +ine 25. Use of uninitialized value in concatenation (.) or string at ./local_t +hreads line 38. $VAR1 = { 'path' => undef, 'foo' => '"find" "" "-type" "f" "-exec" "md5sum" "{}" ";"' }; $VAR2 = { 'path' => undef, 'foo' => '"find" "" "-type" "f" "-exec" "md5sum" "{}" ";"' };

My perl version:

[duelafn@jhegaala tmp]$ perl --version This is perl, v5.8.4 built for i386-linux-thread-multi

Good Day,
    Dean


In reply to Problem localizing $_ using threads::shared by duelafn

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.