Цель заметки --- показать, что иногда проще обойтись без объектов, а использовать замыкания.
Достаточно часто возникает ситуация, когда необходимо многократно произвести некоторое действие, но перед этим провести некоторую подготовительную работу. В объектно ориентированном стиле для этого используется объект с одним единственным методом.
Рассмотрим подобный объект на примере абстрактного "сумматора" чисел. При инициализации "сумматору" передается первоначальное значение, а при каждом вызове метода к текущему значению прибавляется передаваемое. Вот код такого "сумматора" в объектно-ориентированном стиле:
package Foo;
sub new {
my $class = shift;
my $foo = shift;
return bless \$foo;
}
sub foo {
my $self = shift;
$$self += shift;
print $$self, "\n";
}
1;
Пример использования:
use Foo;
my $foo = Foo->new(3);
$foo->foo(1);
$foo->foo(1);
$foo->foo(2);
$foo->foo(2);
Теперь сделаем аналогичный по функционалу "сумматор" с использованием замыкания:
sub make_foo {
my $foo = shift;
return sub {
$foo += shift;
print $foo, "\n";
};
}
Пример использования:
my $foo = make_foo(3);
$foo->(1);
$foo->(1);
$foo->(2);
$foo->(2);
Как видим вариант с замыканием проще, компактней и элегантней.
Пожалуй на этом и остановимся --- читатель дальше сможет сам развить тему. Приведу лишь цитату Стива Маджевски: "Объект --- это совокупность данных вместе с привязанными к ним процедурами... Замыкание --- это процедура вместе с привязанной к ней совокупностью данных."
P.S.
Кстати, Parrot оперирует объектами (PMC),
но при вызовах подпрограмм использует стиль передачи продолжений, который не мыслим без замыканий.
P.P.S
Копия и комментарии находятся на kiev.pm.org
Комментариев нет:
Отправить комментарий