Subject: | building lazy attributes should not harm $_ |
Hi,
When an object with a lazy attribute is first used in a map {} operation, one may loose the first
value of the input list if somewhere in the calling chain for building the attribute, some method
harms the global $_. I paste below a small test case.
Would it be possible to automatically shield $_ before calling the builder of a lazy attribute?
Regards,
Denis
package Classifier;
use strict;
use warnings;
use autodie;
use Moose;
has 'infile' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has '_cache' => (
traits => ['Hash'],
is => 'ro',
isa => 'HashRef',
init_arg => undef,
lazy => 1,
builder => '_build_cache',
handles => {
classify => 'get',
},
);
sub _build_cache {
my $self = shift;
# local $_; # uncomment this to fix the bug
my %cache;
open my $in, $self->infile;
while (<$in>) {
chomp;
my ($name, $cat) = split /:/;
$cache{$name} = $cat;
}
return \%cache;
}
package main;
use Data::Dumper;
my $classifier = Classifier->new( infile => 'cats.data' );
my @names = qw(Tom Mum Roy);
my @cats = map { $classifier->classify($_) } @names;
print Dumper \@names;
print Dumper \@cats;
# content of cats.data
# Kim:family
# Tom:friend
# Tim:foo
# Mum:family
# Dad:family
# Roy:foo