Знаете ли вы, что в PERL'e можно создавать функции по требованию, на лету?
Что это такое и зачем может понадобится?
Скажем, у вас есть функция html_tag:
и вы хотите сделать много функций с названиями соответствующих html тегов. Можно, конечно, вручную написать все определения функций:
но как-то это неправильно, слишком много букв. Оказывается, есть более красивый способ решения этой задачи.
Описываем все необходимые названия функций и добавляем ссылки на них в глобальную таблицу символов пакета. Собственно, вся магия содержится в строке
*$tag = sub { return html_tag($tag,@_); };
sub {} возвращает ссылку на анонимную функцию (внутри которой происходит вызов html_tag с одноименным тегом в качестве первого аргумента).
а присвоение *$tag = добавляет имя функции (содержащееся в переменной $tag) в глобальную таблицу символов пакета (typeglob).
Теперь наши функции можно использовать например так:
А самое главное, для добавления очередной функции достаточно всего-лишь отредактировать строку с именами функций!
Что это такое и зачем может понадобится?
Скажем, у вас есть функция html_tag:
sub html_tag {
my $tag = shift;
my $msg = shift;
return sprintf('<%s>%s</%s>', $tag, $msg, $tag);
}
и вы хотите сделать много функций с названиями соответствующих html тегов. Можно, конечно, вручную написать все определения функций:
sub h1 { return html_tag('h1',@_); }
sub h2 { return html_tag('h2',@_); }
sub h3 { return html_tag('h3',@_); }
...
но как-то это неправильно, слишком много букв. Оказывается, есть более красивый способ решения этой задачи.
my @tags = qw(h1 h2 h3 p div span ul ol li em strong );
for my $tag (@tags) {
no strict 'refs';
*$tag = sub { return html_tag($tag,@_); };
}
Описываем все необходимые названия функций и добавляем ссылки на них в глобальную таблицу символов пакета. Собственно, вся магия содержится в строке
*$tag = sub { return html_tag($tag,@_); };
sub {} возвращает ссылку на анонимную функцию (внутри которой происходит вызов html_tag с одноименным тегом в качестве первого аргумента).
а присвоение *$tag = добавляет имя функции (содержащееся в переменной $tag) в глобальную таблицу символов пакета (typeglob).
Теперь наши функции можно использовать например так:
print
ul(
li('первый пункт').
li('второй пункт').
li('третий пункт')
);
А самое главное, для добавления очередной функции достаточно всего-лишь отредактировать строку с именами функций!