Объект Moose как ленивый хеш

Я хочу заменить некоторые хэши, используемые в моей программе, ленивыми объектами Moose по соображениям производительности. Проблема в том, что есть много кода, который я не контролирую, который, конечно же, использует ->{key} для доступа к элементам. Такой доступ работает с объектами Moose, но не работает с ленивыми до их инициализации:

package Stuff;

use Moose;

has foo => (
   lazy=>1, 
   default=> sub { +{bar=>baz} }
);

package main;
my $x = Stuff->new();

print Dumper $x->{foo}; # undef =(
print Dumper $x->foo;   # {bar => baz }
print Dumper $x->{foo}; # {bar => baz }

Есть ли способ сделать этот первый $x->{foo} инициализирующим переменную?


person letitbee    schedule 09.11.2015    source источник
comment
metacpan.org/pod/Tie::Moose кажется полезным   -  person AKHolland    schedule 09.11.2015
comment
@AKHolland бинго! Хочешь превратить это в ответ, чтобы я мог принять?   -  person letitbee    schedule 10.11.2015
comment
Изменил его в форму ответа. Рад помочь.   -  person AKHolland    schedule 10.11.2015


Ответы (2)


Вы не можете использовать его как хэш напрямую, но с Tie: :Moose вы можете создать хеш, который вызывает базовые методы Moose. Вы можете передать этот хеш другому коду.

use Tie::Moose;

my $x = Stuff->new();
tie my %x, "Tie::Moose", $x;

print Dumper($x{foo}); # { 'bar' => 'baz' }
person AKHolland    schedule 09.11.2015

Итак, вы хотите, чтобы код выполнялся всякий раз, когда осуществляется доступ к элементу вашего хеш-объекта? Это возможно с помощью magic, но это сильно замедлит доступ к вашему объекту.

person ikegami    schedule 09.11.2015
comment
Медленнее, чем что-то вроде return $x->{foo} //= $x->foo() ? - person letitbee; 09.11.2015
comment
Да, потому что альтернатива должна была бы делать это в дополнение к подвызову. - person ikegami; 09.11.2015