PERL: БИБЛИОТЕКА ПРОГРАММИСТА



              

PERL: БИБЛИОТЕКА ПРОГРАММИСТА - стр. 353


Присваивание тип-глобов в сочетании с замыканиями позволяет легко и удоб­но дублировать функции. Представьте, что вам понадобилась функция для гене­рации HTML-кода, работающего с цветами. Например:

Sstring =    red("careful here");

print $string;

<FONT COLORS red ^careful  here</FONT>

Функция red выглядит так:

sub  red  {   "<FONT C0LOR='red'>@_</FONT>"  }

Если вам потребуются другие цвета, пишется нечто подобное:

sub color_font {

my $color = shift;

return "<FONT COLOR='$color'>@_</FONT>"; }

sub red { color_font("red", @_) } sub green { color_font("green", @_) } sub blue { color_font("blue", @_) } sub purple { color_font("purple", @_) } # И т. д.

Сходство функций наводит на мысль, что общую составляющую можно как-то выделить. Для этого следует воспользоваться косвенным присваиванием тип-глобы. Если вы используете рекомендуемую директиву use strict, сначала отклю­чите strict 'refs'для этого блока.

gcolors = qw(red blue green yellow orange purple violet); for my $name (©colors) {

no strict 'refs';

¦$narae = sub { "<FONT COLOR='$name'>

Функции кажутся независимыми, однако фактически код был откомпилиро­ван лишь один раз. Подобная методика экономит время компиляции и память. Для создания полноценного замыкания все переменные анонимной подпрограм­мы должны быть лексическими. Именно поэтому переменная цикла объявляется с ключевым словом ту.

Перед вами одна из немногочисленных ситуаций, в которых создание прото­типа для замыкания оправдано. Если вам захочется форсировать скалярный кон­текст для аргументов этих функций (вероятно, не лучшая идея), ее можно запи­сать в следующем виде:


10.15. Перехват вызовов неопределенных функций с помощью AUTOLOAD   371

.$name = sub ($) { '^FONT COLOR='$name'>$_[0]</F0NT>" };

Однако прототип проверяется во время компиляции, поэтому приведенное выше присваивание произойдет слишком поздно и никакой пользы не принесет. Следовательно, весь цикл с присваиваниями следует включить в BEGIN-блок, что­бы форсировать его выполнение при компиляции.




Содержание  Назад  Вперед