[Melbourne-pm] quirky behaviour of 'local'...

Toby Corkindale toby.corkindale at strategicdata.com.au
Mon Jul 25 23:27:23 PDT 2011


On 26/07/11 16:07, Mathew Robertson wrote:
> Hi all,
>
> As a result of some hacking on some code, I identified some quirky
> behaviour with regards to 'local'...   I have whittled the problem down
> to it simplest form - see below.
>
> Basically speaking, I would have expected the inner-array-variable to
> become localised to block scope.  Is there something that I am missing here?

What is happening here is a quirk of how Perl does multi-level data 
structures..

$HANDLERS{c} contains a reference to an array.
When you localise $HANDLERS{c} you are localising the value of that 
reference.. not the actual data in the referenced thing.

You can achieve the result you're looking for with this mess:

use Storable qw(dclone);
{
   # local $HANDLERS{c} = $HANDLERS{c};
   local $HANDLERS{c} = dclone($HANDLERS{c});
   push @{$HANDLERS{c}}, 'u';
   print Dumper(\%HANDLERS);
}


> #!/usr/bin/perl
> use strict;
> use warnings FATAL => 'all';
> use Data::Dumper; $Data::Dumper::Indent = 1; $Data::Dumper::Sortkeys = 1;
> our %HANDLERS;
>
> # This block, as expected, de-localises %HANDLERS at block scope.
>
> $HANDLERS{a} = sub {};
> $HANDLERS{b} = sub {};
> print Dumper(\%HANDLERS);
> {
>    local %HANDLERS = %HANDLERS;
>    $HANDLERS{c} = 't';
>    print Dumper(\%HANDLERS);
> }
> print Dumper(\%HANDLERS);
>
> print "-" x 50 . $/;
>
> # Unexpectedly, no de-localising of %HANDLERS at block scope.
> # I would have expected $HANDLERS{c} to be localised.
>
> $HANDLERS{c} = ['t'];
>
> print Dumper(\%HANDLERS);
> {
> #  local %HANDLERS = %HANDLERS;
>    local $HANDLERS{c} = $HANDLERS{c};
> #  local @{$HANDLERS{c}} = @{$HANDLERS{c}};
>    push @{$HANDLERS{c}}, 'u';
>    print Dumper(\%HANDLERS);
> }
> print Dumper(\%HANDLERS);
>
>
>
> _______________________________________________
> Melbourne-pm mailing list
> Melbourne-pm at pm.org
> http://mail.pm.org/mailman/listinfo/melbourne-pm


-- 
.signature


More information about the Melbourne-pm mailing list