Хотелось бы сразу предупредить: Это статья предназначена не для зубров, а описывает вполне обычный трюк с 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 вызовов в секунду во втором случае. Скорость вырастает втрое.
