Pull to refresh

Функции по требованию

Reading time1 min
Views459
Знаете ли вы, что в PERL'e можно создавать функции по требованию, на лету?
Что это такое и зачем может понадобится?

Скажем, у вас есть функция 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('третий пункт')
 );



А самое главное, для добавления очередной функции достаточно всего-лишь отредактировать строку с именами функций!

Tags:
Hubs:
Total votes 11: ↑5 and ↓6-1
Comments19

Articles