POD2-RU

 view release on metacpan or  search on metacpan

lib/POD2/RU/perlmod.pod  view on Meta::CPAN

    sub identify_typeglob {
        my $glob = shift;
        print 'You gave me ', *{$glob}{PACKAGE}, '::', *{$glob}{NAME}, "\n";
    }
    identify_typeglob *foo;
    identify_typeglob *bar::baz;

Это выведет

    You gave me main::foo
    You gave me bar::baz

Нотация C<*foo{THING}>  может также использоваться для получения ссылки на
отдельные элементы *foo. Смотрите L<perlref>.

Определение подпрограммы  (и объявления(declarations), коль на то пошло) 
не обязательно должно находиться в пакете, символьную таблицу которого они
занимают. Вы можете определить подпрограмму за пределами пакета
явно квалифицируя имя подпрограммы:

    package main;
    sub Some_package::foo { ... }   # &foo определяется в пакете Some_package

Это просто краткая запись для присвоения тайпглобу (typeglob) во время компиляции:

    BEGIN { *Some_package::foo = sub { ... } }

и это I<не> то же самое, что писать:

    {
	package Some_package;
	sub foo { ... }
    }

В первых двух версиях тело подпрограммы лексически лежит
 в основном пакете, а I<не> в Some_package. Так
что-то вроде этого:

    package main;

    $Some_package::name = "fred";
    $main::name = "barney";

    sub Some_package::foo {
	print "in ", __PACKAGE__, ": \$name is '$name'\n";
    }

    Some_package::foo();

напечатает:

    in main: $name is 'barney'

вместо:

    in Some_package: $name is 'fred'

Это также имеет последствия для использования SUPER:: квалификатор
(См. L<perlobj>).

=head2 BEGIN, UNITCHECK, CHECK, INIT и END
X<BEGIN> X<UNITCHECK> X<CHECK> X<INIT> X<END>

Существуют блоков специально именованного кода, которые выполняются в начале и в
в конце работающей программы Perl. Это блоки C<BEGIN>,
C<UNITCHECK>, C<CHECK>, C<INIT>, и C<END>.

Эти блоки кода могут быть префиксом C<sub>, что дать внешний вид
подпрограммы (хотя это не считается хорошим стилем). Следует отметить
что эти блоки кода в действительности не существуют как именованные подпрограммы (несмотря на
их внешний вид). Эти блоки дают такую возможность, что вы можете иметь
B<более, чем один> такой блок кода в программе, и они 
B<все> будут выполнены в соответствующий момент. 
Таким образом вы не можете выполнять любой из 
этих блоков кода по имени.

Блок кода C<BEGIN> выполняется как можно скорее, как только он полностью определён
 даже до анализа остального содержимого файла (или строки). 
Вы можете иметь несколько блоков C<BEGIN> внутри файла (или в
выполняемой eval'ом строке); они будут выполнены в порядке определения. Потому что блок C<BEGIN>
выполняется немедленно, он может вытащить определения подпрограмм
и тому подобного из других файлов во времени, чтобы быть видимым для остальной части во времени компиляции
и во время выполнения (compile and run time). После того как блок C<BEGIN> закончился он сразу неопределенным (undefined) и любой
используемый код возвращает в Perl пул своей памяти (memory pool).


Блок кода C<END> выполняется настолько поздно насколько это возможно
, то есть, после того, как Perl завершает выполнение программы и сразу перед тем, как 
интерпретатор выйдет (is being exited), даже если это выход в результате функции die().
(Но если он перетекает в другую программу через C<exec>, или
выдувается из воды по сигналу--вы должны перехватить (trap) это сами
(если вы можете).) Вы можете иметь несколько C<END>блоков в файле--они
будет выполняться в обратном порядке определения; то есть: последний пришел, первый
вышел (last in, first out) (LIFO). C<END> блоки не выполняются при запуске perl с
 ключем C<-c>, или, если происходит сбой компиляции.

Обратите внимание, что блоки кода C<END> B<не> выполняются в конце строки
C<eval()>: если любые блоки кода C<END> создаются в строке C<eval()>,
то они будут выполняться так же, как любой другой C<END> блок пакетного кода
в порядке LIFO сразу перед тем, как интерпретатор будет выходить (just before the interpreter is being exited).

Внутри блока C<END>, C<$?> содержит значение, которые программа
собирается передать C<exit()>. Вы можете изменить C<$?>, чтобы изменить выходное (exit
value of the program) значение программы. Остерегайтесь изменения C<$?> случайно (например, запуск чего-то через C<system>).
X<$?>

Внутри блока C<END>, значение C<${^GLOBAL_PHASE}> будет C<"END">.

Блоки кода C<UNITCHECK>, C<CHECK> и C<INIT> являются полезными для того, чтобы поймать
переход между фазой компиляции и фазой выполнения
основной программы(execution phase of the main program).

Блоки C<UNITCHECK> выполняются только после того, как юнит, определенный им будет откомпилирован. 
Файл основной программы и каждый загружаемый ей модуль - это
единицы компиляции, такие как строка C<eval>s, во время выполнения код компилируется с помощью
конструкции C<(?{ })> в регексе, вызова C<do FILE>, C<require FILE>,
и кода после ключа C<-e> командной строки.

Блоки C<BEGIN> и C<UNITCHECK> не связаны непосредственно фазами
интерпретатора Perl. Они могут быть созданы и выполняться во время любой фазы.

Блоки кода C<CHECK> выполняются только после фазы окончания B<начальной> компиляции Perl
и до начала времени выполнения (run time), в порядке LIFO. Блоки кода C<CHECK> используются 
в комплекте компилятора Perl (Perl compiler suite) для сохранения скомпилированного состояния программы.

Внутри блока C<CHECK>, значение переменной C<${^GLOBAL_PHASE}> будет C<"CHECK">.

Блоки C<INIT> выполняются сразу перед началом времени выполнения Perl (Perl runtime begins execution), 
 в последовательности "первый вошел, первый вышл" (FIFO).

Внутри блока C<INIT> , значение C<${^GLOBAL_PHASE}> будет C<"INIT">.

Блоки C<CHECK> и C <INIT> в коде компилируются с помощью C<require>, строкой C <do>,
или строкой C<eval> не будет выполняться, если они возникают после окончания
фазы основной компиляции; Это может быть проблемой в mod_perl и других стойких
средах (persistent environments), использующих эти функции для загрузки кода во время выполнения.

При использовании ключей B<-n> и B<-p> в Perl, C<BEGIN> и C<END>
 работают так же, как они работают в B<awk>, как вырожденный случай.
Оба и C<BEGIN> и C<CHECK> блоки выполняются при использовании ключа B<-c>
 для компиляции только для проверки синтаксиса , хотя основной код
не выполняется.

Программа B<begincheck> показывает ясно это поведение, в конечном счете:

  #!/usr/bin/perl

  # begincheck

  print         "10. Ordinary code runs at runtime.\n";

  END { print   "16.   So this is the end of the tale.\n" }
  INIT { print  " 7. INIT blocks run FIFO just before runtime.\n" }
  UNITCHECK {
    print       " 4.   And therefore before any CHECK blocks.\n"
  }
  CHECK { print " 6.   So this is the sixth line.\n" }

  print         "11.   It runs in order, of course.\n";

  BEGIN { print " 1. BEGIN blocks run FIFO during compilation.\n" }
  END { print   "15.   Read perlmod for the rest of the story.\n" }
  CHECK { print " 5. CHECK blocks run LIFO after all compilation.\n" }
  INIT { print  " 8.   Run this again, using Perl's -c switch.\n" }

  print         "12.   This is anti-obfuscated code.\n";

  END { print   "14. END blocks run LIFO at quitting time.\n" }
  BEGIN { print " 2.   So this line comes out second.\n" }
  UNITCHECK {
   print " 3. UNITCHECK blocks run LIFO after each file is compiled.\n"
  }
  INIT { print  " 9.   You'll see the difference right away.\n" }

  print         "13.   It merely _looks_ like it should be confusing.\n";

  __END__

  #!/usr/bin/perl

  # begincheck_ru

  print         "10. Обычный код, работающий во время выполнения.\n";

  END { print   "16.  Так что это конец сказки.\n" }
  INIT { print  " 7. Блоки INIT запускают FIFO непосредственно перед рантаймом (runtime).\n" }
  UNITCHECK {
    print       " 4.   И поэтому перед любым блоком CHECK.\n"
  }
  CHECK { print " 6.   Так что это шестая строка.\n" }

  print         "11.   Она выполняется последовательно, конечно.\n";

  BEGIN { print " 1. BEGIN блоки запускаются FIFO во время компиляции.\n" }
  END { print   "15.   Читайте perlmod для остальной части рассказа.\n" }
  CHECK { print " 5. CHECK блоки запускаются LIFO после всей компиляции.\n" }
  INIT { print  " 8.   Запустить это снова, используя ключ Perl -c.\n" }

  print         "12.   Это анти запутанный код.\n";

  END { print   "14. END блоки запускаются LIFO во время времени выходя из программы.\n" }
  BEGIN { print " 2.   Так что эта линия выходит второй.\n" }
  UNITCHECK {
   print " 3. UNITCHECK блоки запускаются LIFO после того, как каждый файл откомпилируется.\n"
  }
  INIT { print  " 9.   Вы сразу увидите разницу.\n" }

  print         "13.   Это просто _выглядит_ так, как она должна быть запутанным. (It merely _looks_ like it should be confusing.)\n";

  __END__

=head2 Perl Классы
X<class> X<@ISA>

Не существует специального синтаксиса класса в Perl, но пакет может действовать
как класс, если он предоставляет подпрограммы в качестве методов. Такие
пакеты могут также предоставить некоторые из методов его от другого класса (пакета)
перечисляя другие имена пакета в глобальной массиве @ISA  (который
должен быть глобальным пакетом, не локальным (package global, not a lexical)).

Подробнее об этом см. L<perlootut> и L<perlobj>.

=head2 Perl Модули
X<module>

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

Например чтобы начать традиционный, не-OO модуль под названием Some::Module,
создайте файл с именем F<Some/Module.pm> и начните с помощью этого шаблона:

    package Some::Module;  # assumes Some/Module.pm

    use strict;
    use warnings;

    BEGIN {
        require Exporter;

        # set the version for version checking
        our $VERSION     = 1.00;

        # Inherit from Exporter to export functions and variables
        our @ISA         = qw(Exporter);

        # Functions and variables which are exported by default
        our @EXPORT      = qw(func1 func2);

        # Functions and variables which can be optionally exported
        our @EXPORT_OK   = qw($Var1 %Hashit func3);
    }

    # exported package globals go here
    our $Var1    = '';
    our %Hashit  = ();

    # non-exported package globals go here
    # (they are still accessible as $Some::Module::stuff)



( run in 1.126 second using v1.01-cache-2.11-cpan-39bf76dae61 )