http://www.perlmonks.org?node_id=1023787


in reply to Localizing hash keys in an AoH

Guards.

use strict; use warnings; use Data::Dumper; sub localised { package localised; my ($ref, $new) = @_; my $old = $$ref; $$ref = $new; return bless [$ref, $old]; sub DESTROY { my ($ref, $old) = @{+shift}; $$ref = $old; } } my @data = ( { unit => 'S', value => 50 }, { unit => 'T', value => 60 }, { unit => 'Q', value => 70 }, ); LOCAL_BLOCK_1: { my @guards = map localised(\$data[$_]{unit}, "S"), 0 .. $#data; print Dumper \@data; } # Note that @guards has gone out of scope. # Hey, presto... DESTROY gets called! print Dumper \@data;
package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Replies are listed 'Best First'.
Re^2: Localizing hash keys in an AoH
by kennethk (Abbot) on Mar 15, 2013 at 22:49 UTC

    Very nice. I think this one would give my coworkers tremendous pause, but this will work in the general case, whereas NetWallah's solution fails if we have some more grotesque AoHoAoAoH thing going on.

    Update: And it actually gives you tremendous control over localization scope, since you can stash the guard at whatever level you want. Nice.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      It could be made more readable. Defining entire packages within a sub is a trick I'm fond of, but I'm aware it's not everybody's cup of tea.

      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

      Indeed, but you don't really need to wait for the guard to go out of scope. It's just a blessed object, so you can call $guard->DESTROY manually any time you like.

      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name