Лексические переменные в Perl 6

от автора

Одна из проблем программирования – борьба с возрастающей сложностью программ при возрастании их объёма. Исторически она решается путём изолирования отдельных частей программ, взаимодействие которых друг с другом ограничено. Такой подход действует на всех уровнях программирования – «разделение концепций», «делай что-то одно и делай это хорошо», BCNF, монады, процедуры, классы, роли, модули. Все они поощряют ограничение частей программы, чтобы не играть против комбинаторики. Простейшим примером логического разделения является лексическая переменная.

{     my $var;     # $var доступна тут } # $var а тут недоступна 

Что же в этом интересного?

С самого начала Perl поступал с этим неверно. По умолчанию, область видимости переменных в Perl 5 – это переменная модуля, нечто типа глобальной переменной. Если вы определите что-либо внутри блока, оно будет видно снаружи.

$ perl -v This is perl 5, version 12, subversion 1 (v5.12.1)  $ perl -E '{ $var = 42 }; say $var' 42  $ perl -wE '{ my $var= 42 }; say $var' Name "main::var" used only once: possible typo at -e line 1. Use of uninitialized value $var in say at -e line 1. 

В Perl 6 лексические переменные работают по умолчанию.

$ perl6 -e '{ $var = 42 }; say $var'    # необходима инициализация через 'my' ===SORRY!=== Symbol '$var' not predeclared in <anonymous>  $ perl6 -e '{ my $var = 42 }; say $var' # не будет работать – не видна снаружи ===SORRY!=== Symbol '$var' not predeclared in <anonymous> 

Ну хорошо, может это поможет поймать опечатку… Но главное преимущество этого в том, что вы будете работать с честными областями видимости переменных. И это позволит вам управлять сложностью программ.

Конечно, Perl 5 не заставлял вас программировать «правильно» и не навязывал использование strict и warnings. Perl 5 обещал обеспечивать обратную совместимость, а Perl 1 явно не было предназначен для написания сложных программ. У глобальных переменных в небольших скриптах есть смысл.

Perl 6 пытается помочь вам начать с малого и добавлять поддержку структурирования по мере роста программ. В случае переменных это означает, что в скриптах и модулях переменные лексические по умолчанию, но в однострочниках, вызываемых по –е, остаются глобальные переменные.

Если вы думали, что по поводу лексических переменных всё – это не так. В этом подходе есть неожиданные бонусы. Рассмотрим функцию:

sub counter($start_value) {     my $count = $start_value;     return { $count++ }; } 

Возвращается блок кода. При каждом вызове counter мы получаем кусочек кода, который можно вызвать нужно количество раз.

Вот что произойдёт, если мы создадим два разных кусочка этого кода и поиграем с ними:

my $c1 = counter(5); say $c1();           # 5 say $c1();           # 6  my $c2 = counter(42); say $c2();           # 42 say $c1();           # 7 say $c2();           # 43 

Видите? $c1 и $c2 работают независимо. У каждого сохраняется состояние в виде переменной $count. Для нас она может выглядеть, как одна переменная, но для двух разных экземпляров counter это две разные области хранения значения – поскольку, каждый раз заново входя в блок, мы открываем новую область видимости. Такой блок называется замыканием.

Если вам показалось, что замыкания похожи на облегчённые объекты – поздравляю, это именно так. Их суть ограничения доступа та же, что у инкапсуляции и сокрытия информации в ОО. Это всё нужно для ограничения поля деятельности, чтобы отдельные части программы могли натворить как можно меньше дел.

ссылка на оригинал статьи http://habrahabr.ru/post/253133/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *