Ниже приведен отрывок из некоторого кода, с которым я экспериментирую:
has buffer => ( is => 'rw', isa => 'ScalarRef' );
has old_stdout => ( is => 'rw', isa => 'FileHandle' );
sub capture {
my $self = shift;
my $old_stdout;
my $buffer;
open $old_stdout, '>&', STDOUT
or croak 'Cannot duplicate filehandle';
close STDOUT;
open STDOUT, '>', \$buffer
or croak 'Cannot open filehandle';
$self->old_stdout( $old_stdout );
$self->buffer( \$buffer );
}
sub reset {
my $self = shift;
open STDOUT, '>&', $self->old_stdout
or croak 'Cannot reset STDOUT';
}
В другом месте:
my $stdout = Capture->new();
print "Some output\n";
$stdout->reset();
print $stdout->buffer();
# SCALAR(0x#######)
print ${$stdout->buffer()};
# Some output
Я попытался обмануть, установив атрибут hashref напрямую - он работает, но мне не нравится это делать:
open STDOUT, '>', \$self->{buffer}
or croak 'Cannot open filehandle';
Я думаю, что мне здесь не хватает чего-то фундаментального. Как мне сохранить $buffer
(файл в памяти) в качестве атрибута Moose, чтобы я мог получить его позже, не обращаясь к вызывающему объекту?
Обновление
Я добавил модификатор метода around
, который добивается цели:
around 'buffer' => sub {
my $orig = shift;
my $self = shift;
return ${$self->$orig} unless @_;
$self->$orig( @_ );
};
... но это все еще кажется грязным. Есть ли лучший способ?