Хотелось бы сразу предупредить: Это статья предназначена не для зубров, а описывает вполне обычный трюк с AUTOLOAD.
В Perl существует замечательная возможность отрабатывать вызовы к неопределённым методам.
Например, в случае
Результат будет равен 'any data'.
Недостаток у этого способа фактически один — низкая производительность при повторных вызовах.
Исправит это поведение генерация методов на лету.
Помимо разного рода кастомных акцессоров (я искренне рекомендую Class::Accessor::Fast, где возможно), очень часто полезно для написания врапперов, вокруг обьектов, от которых нельзя отнаследоваться (например, нужен хэш, а обьект является хэндлом XS).
Судя по пакету Benchmark, создание обьекта и 100-кратный вызов неизвестного метода на сервере (FreeBSD/x64/Perl5.8.8) даёт в первом случае до 3400 вызовов в секунду, и до 11000 вызовов в секунду во втором случае. Скорость вырастает втрое.
Введение
В Perl существует замечательная возможность отрабатывать вызовы к неопределённым методам.
Например, в случае
package Something;
our $AUTOLOAD;
sub AUTOLOAD
{
return 'any data';
}
sub DESTROY
{
}
package XTest;
my $o = new Something();
print $o->dry();
Результат будет равен 'any data'.
Недостатки
Недостаток у этого способа фактически один — низкая производительность при повторных вызовах.
Генерация методов на лету
Исправит это поведение генерация методов на лету.
package Something;
our $AUTOLOAD;
sub AUTOLOAD
{
my ($self) = @_;
my $name = $AUTOLOAD;
return if $name =~ /^.*::[A-Z]+$/;
$name =~ s/^.*:://; # strip fully-qualified portion
my $sub = sub
{
my $self = shift();
return 'any data';
};
no strict 'refs';
*{$AUTOLOAD} = $sub;
use strict 'refs';
goto &{$sub};
}
package XTest;
my $o = new Something();
print $o->dry();
Где это полезно
Помимо разного рода кастомных акцессоров (я искренне рекомендую Class::Accessor::Fast, где возможно), очень часто полезно для написания врапперов, вокруг обьектов, от которых нельзя отнаследоваться (например, нужен хэш, а обьект является хэндлом XS).
Производительность
Судя по пакету Benchmark, создание обьекта и 100-кратный вызов неизвестного метода на сервере (FreeBSD/x64/Perl5.8.8) даёт в первом случае до 3400 вызовов в секунду, и до 11000 вызовов в секунду во втором случае. Скорость вырастает втрое.