=encoding utf8

=head1 NAME/НАИМЕНОВАНИЕ

perlmod - Perl модули (пакеты и таблицы симолов)

=head1 ОПИСАНИЕ

=head2 Пакеты
X<package> X<namespace> X<variable, global> X<global variable> X<global>

Perl предоставляет механизм изменения пространства имен для защиты пакетов от
засорения друг друга всеми своими переменными. Фактически, в Perl нет такой 
вещи, как глобальные переменные. Инструкция package объявляет единицу
компиляции, находящуюся в данном пространстве имен. Область действия
объявления пакета начинается от самого объявления и простирается до конца
окружающего блока, C<eval> или файла, в зависимости от того, что будет первым
(такую же область имеют операторы my() и local()). Неполные (неквалифицированные)
динамические идентификаторы будут находится в этом пространстве имен, за 
исключением тех немногих идентификаторов, которые, будучи
неквалифицированными, по умолчанию находятся в пакете main, как будет описано
ниже. Инструкция package затрагивает только динамические
переменные--включая те, к которым применили local() -- но I<не> лексические 
переменные, создаваемые при помощи my(). Обычно package будет первым
объявлением в файле, который вы подключаете используя операторы C<do>,
C<require> или C<use>. Вы можете переключится в пакет в различных местах; это
переключение влият только на то, какая таблица символов будет использоваться
компилятором до конца этого блока. На переменные и файловые указатели в пакете
можно ссылаться из других пакетов, предваряя имя переменной именем пакета и
двойным двоеточием: C<Package::Variable>. Если имя пакета отсутствует,
подразумевается пакет main. То есть C<$::sail> эквивалентно C<$main::seil>.

В старых пакетах разделителем пакета служила одинарная кавычка, но сейчас
предпочтительно использовать двойное двоеточие, оно более человекочитаемо, и
также лучше читается в макросах B<emacs>. 

Также два двоеточия позволяют С++ программистам чувствовать, 
что они понимают, что происходит -- в отличии от 
разделителя одинарная кавычка, позволявшей испытывать похожее чувство Ada
программистам. Поскольку старомодный синтаксис все еще поддерживается для
обеспечения обратной совместимости, если вы попытаетесь использовать подобную
строку C<"This is $owner's house">, вы обратитесь к C<$owner::s>; то есть, к
переменной $s в пакете C<owner>, что вероятно не то, что вы хотели.
Используйте фигурные скобки для устранения неоднозначности, как здесь C<"This is ${owner}'s house">.
X<::> X<'>

Пакеты сами могут содержать разделители пакетов, например
C<$OUTER::INNER::var>. Однако это ничего не подразумевает о порядке поиска 
имен. Нет относительных пакетов: все символы либо локальны в текущем пакете, 
либо должны быть полностью квалифицированы от внешнего пакета.  Например, в 
пакете C<OUTER> ничто не позволит C<$INNER::var> относиться к 
C<$OUTER::INNER::var>. C<INNER> относится к полностью отдельному глобальному 
пакету.

В таблице символов пакета хранятся только идентификаторы, начинающиеся с 
буквы или знака подчеркивания. Все другие символы, включая пунктуационные
переменные подобно C<$_>, хранятся в пакете C<main>. В добавок, идентификаторы 
STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC и SIG, если они не
квалифицированы, принудительно помещаются в C<main>, даже когда они
используются для других целей, нежели предназначены изначально.  Если вы 
назовете свои пакеты C<m>, C<s> или C<y>, вы не сможете использовать
квалифицированую форму идентификатора, поскольку она будет интерпретирована
как поиск по шаблону, замена или транслитерация, соответственно.
X<variable, punctuation> 

Переменные, начинающиеся с нижнего подчеркивания, ранее использовались для
принудительного помещения в пакет C<main>, но мы решили, что они более полезны
разработчикам пакетов для индикации имен приватных переменных и методов. 
Однако, имена переменных и функций, состоящие из едиственного C<_>, такие как 
C<$_> или C<sub _>, по прежнему принудительно находятся в пакете C<main>.
Смотрите также L<perlvar/"The Syntax of Variable Names">.

Обрабатываемые C<eval>-ом строки компилируются в том же пакете, в котором
компилируется eval(). (Однако, при присваивании C<$SIG{}> полагается, что
обработчик сигнала определен в пакете C<main>. Квалифицируйте имя обработчика
сигнала, если хотите использовать обработчик сигнала из пакета.) Для примера
взгляните на F<perldb.pl> из библиотеки Perl. В начале работы он переключается
на пакет C<DB> так, что отладчик не мешает работать с переменными в
отлаживаемой программе.

В различных точках, однако он
временно переключает обратно в пакет (package) C<main> для выполнения различных
выражений в контексте пакета C<main> (или в том пакете, откуда вы пришли). 
Смотрите L<perldebug>.

Специальный символ C<__PACKAGE__> содержит текущий пакет (package), но не может
(легко) использоваться для создания имен переменных.

Смотрите L<perlsub> для вопросов, связанных (for other scoping issues related) с my() и local() 
и L<perlref> для описания замыканий (regarding closures).

=head2 Таблицы символов (Symbol Tables)
X<symbol table> X<stash> X<%::> X<%main::> X<typeglob> X<glob> X<alias>

Таблица символов пакета храниться в хэше с именем, за которым идут два двоеточия.
Главной таблицей символов, таким образом, будет C<%main::>, или C< %:: > для краткости. 
Аналогичным образом таблицой символов для вложенных пакетов
является упоминаемое ранее имя C<%OUTER::INNER::>.

Значением в каждой записи хэша является то, что вы имеете в виду когда вы
используйте typeglob (глобальный тип) нотацию C<*name>.

    local *main::foo    = *main::bar;

Вы можете использовать это, например для того, чтобы распечатать все переменные в пакете.
Стандартная, но устаревшая библиотека F<dumpvar.pl> и CPAN модуль Devel::Symdump используют это.

Результаты создания новых записей в таблице символов непосредственно или изменение любой
записи, которые уже не являются typeglobs, не определены и являются предметом изменения
 в следующих релизах perl (subject to change between releases of perl). 

Присвоение тайпглобу (глобальном типу, typeglob) выполняет операцию алиасирования (сделать псевдоним, синонимирования, другое имя тому же объекту), т.е.
(Assignment to a typeglob performs an aliasing operation, i.e.,)

    *dick = *richard;

приводит к тому, что переменные, подпрограммы, форматы и дескрипторы  файлов и каталогов
доступные через идентификатор C<richard> также будут быть доступны через
идентификатор C<dick>. Если, вместо этого, вы хотите сделать алиас (псевдоним) 
только для конкретной переменной или подпрограммы, присвойте ссылку:

    *dick = \$richard;

Что делает $richard и $dick той же переменной, но оставляет
@richard и @dick независимыми массивами. Хитро, да? (Tricky, eh?)

Существует один тонкое (subtle) различие между следующими инструкциями:

    *foo = *bar;
    *foo = \$bar;

C<*foo = *bar> делает тайпглобы синонимами на самих себя, тогда как (makes the typeglobs themselves synonymous while)
C<*foo = \$bar> делает СКАЛЯРНЫЕ части  двух отдельных тайпглобов (typeglobs) СКАЛЯРНЫХ portions of two distinct typeglobs
ссылающимися на теже скалярное значение (refer to the same scalar value). Это означает, что следующий код:

    $bar = 1;
    *foo = \$bar;       # Делает $foo алиасом для $bar

    {
        local $bar = 2; # Изменение ограничено блоком (Restrict changes to block)
        print $foo;     # Напечатает '1'!
    }

Будет печатать '1',  потому что C<$foo> содержит ссылку на I<оригинал>
C<$bar>. На тот, который был наполнен независимо от C<local()> и, который будет
восстановлен, когда блок закончится. Поскольку переменные доступны через
тайпглоб (typeglob), вы можете использовать  C<*foo = *bar>, чтобы создать псевдоним, который будет
локальным. (Однако следует знать, что это означает, что вы не сможете иметь отдельных
C<@foo> и C<@bar>, и т.д.)

Все это становится важным, потому что модуль Exporter использует глоб алиасинг (glob
aliasing ) как механизм импорта/экспорта. Сможете ли вы или нет правильно
локализовать переменную, которая была экспортирована из модуля зависит от того, как
эта она экспортировалась:

    @EXPORT = qw($FOO); # Обычная форма, не можеть быть локализована
    @EXPORT = qw(*FOO); # Можеть быть локализована

Вы можете обойти (work around) это в первом случае, 
используя полное имя (C<$Package::FOO>) там, где требуется локальное значение, 
или путем переопределения его сказав, C<*FOO = *Package::FOO> в скрипте.

Механизм C<*x = \$y>  может использоваться для передачи и возврата дешевой ссылки
в или из подпрограмм, если вы не хотите, копировать переменную целиком. 
Это работает только при присваивании динамических переменных, не лексических.

    %some_hash = ();			# не может быть my()
    *some_hash = fn( \%another_hash );
    sub fn {
	local *hashsym = shift;
	# теперь используем %hashsym нормально, и вы
	# будет влиять на вызвавшего процедуру (caller's) %another_hash
	my %nhash = (); # делаете то, что вы хотите
	return \%nhash;
    }

По возврате значения из процедуры, ссылка будет перезаписывать хэш слот в
таблице символов, указанный в тайпглобе *some_hash. 
Это несколько хитрый способ передачи сылки дешево,
когда вы не хотите помнить обязанность разыменовать переменные
явным образом.

Другое использование таблиц символов — для создания "постоянных" скаляров.
X<constant> X<scalar, constant>

    *PI = \3.14159265358979;

Теперь вы не сможете изменить C<$PI>, что, вероятно, является, в общем, хорошей вещью.
Это не то же самое, как постоянная подпрограмма, которая подлежит
оптимизации во время компиляции. Постоянная подпрограмма (constant subroutine) является одним прототипом
не принимающим аргументов и возвращает константное выражение. См.
L<perlsub> для подробной информации о них. Прагма C<use constant> является
удобным сокращением для этого.

Вы можете распечтатать значения C<*foo{PACKAGE}> и C<*foo{NAME}>, чтобы узнать, из какого имени и
 из какого пакета появляется *foo в таблице символов. Это может быть полезным
в подпрограмме, которой передаются тайпглобы в качестве аргументов:

    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)
    our @more    = ();
    our $stuff   = '';

    # file-private lexicals go here, before any functions which use them
    my $priv_var    = '';
    my %secret_hash = ();

    # here's a file-private function as a closure,
    # callable as $priv_func->();
    my $priv_func = sub {
        ...
    };

    # make all your functions, whether exported or not;
    # remember to put something interesting in the {} stubs
    sub func1      { ... }
    sub func2      { ... }

    # this one isn't exported, but could be called directly
    # as Some::Module::func3()
    sub func3      { ... }

    END { ... }       # module clean-up code here (global destructor)

    1;  # don't forget to return a true value from the file

Затем перейдите к декларации и использовании переменных в функциях без
какой-либо квалификации. См. L<Exporter> и L<perlmodlib> для
 более подробной информация по вопросам механики и стиля создания модуля.

Perl модули могут быть включены в вашу программу с помощью объявления

    use Module;

или

    use Module LIST;

Это точно эквивалентно

    BEGIN { require 'Module.pm'; 'Module'->import; }

или

    BEGIN { require 'Module.pm'; 'Module'->import( LIST ); }

Как особый случай

    use Module ();

это эквивалентно

    BEGIN { require 'Module.pm'; }

Все файлы Perl модулей  имеют расширение F<.pm>. Оператор C<use>
предполагает это, так что вам не нужно писать точно "F<Module.pm>" в кавычках.
Это также помогает разделять новые модули от старых F<.pl> и
F<.ph> файлов. Имена модулей также пишутся большими буквами (капитализируются), если они не
функционируют как прагмы; прагмы здесь выступают, как директивы компилятора,
и иногда называются "прагматичными модулями" ( "pragmatic modules") (или даже "pragmata"
если вы являетесь последователем классицизма).

Эти два выражения:

    require SomeModule;
    require "SomeModule.pm";

отличаются друг от друга в двух случаях. В первом случае, любое двойное
двоеточие в имени модуля, например C<Some::Module>, переводятся
в вашей системе в разделитель каталогов, обычно "/". Второй случай  в том, что
 имя и должно быть указаны буквально. Другая
разница в том, что видя первый C<require> клей в компиляторе
использующий косвенное дополнение нотации с участием "SomeModule", как
в C<$ob = purge SomeModule>, является вызовом метода, а не вызов функции.
(Да, в этом действительно может быть различие.)

Потому что выражение C<use> подразумевает блок C<BEGIN>, импорт
семантики происходит, как только инструкция C<use> компилируется,
перед компиляцией остальной части файла. Это то, как это может
функционировать в качестве pragma механизма, а также как модули способны
объявите подпрограммы, которые затем отображаются как список или унарные операторы для
остальной части текущего файла. Это не будет работать, если вы используете C<require>
вместо C<use>. С C<require> вы можете попасть в такую проблему:

    require Cwd;		# make Cwd:: accessible
    $here = Cwd::getcwd();

    use Cwd;			# import names from Cwd::
    $here = getcwd();

    require Cwd;	    	# make Cwd:: accessible
    $here = getcwd(); 		# oops! no main::getcwd()

В общем, больше рекомендуется C<use Module ()>, чем C<require Module>,
потому что он определяет наличие модуля во время компиляции, а не в
середине выполнения программы. Исключение было бы, если два модуля, где
каждый пытается C<use> друг друга и каждый также называется функцией из
этого модуля. В этом случае просто используйте C<require> вместо C<use>.

Perl пакеты могут быть вложены в другие имена пакетов, поэтому мы можем иметь
имена пакетов, содержащих C<::>. Но если мы использовали это имя пакета
непосредственно в качестве имени файла он будет для нас громоздким или невозможным
именем файла на некоторых системах. Поэтому, если имя модуля, скажем,
C<Text::Soundex>, то его определение на самом деле находится в библиотеке
файла F<Text/Soundex.pm>.

Модули Perl всегда имеют файл F<.pm>, но там также могут быть
динамически связанные исполняемые файлы (часто заканчиваются на F<.so>) или автозагружаемые
определения подпрограмм (autoloaded subroutine definitions)  (часто заканчиваются в F<.al>), связанные с
модулем. Если это так, то они будут полностью прозрачны для пользователя
модуля. На файле F<.pm> лежит ответственность по загрузке
(или организации автозагрузки) любых дополнительных функциональных возможностей. Например,
хотя для модуль POSIX случается делать и динамическую загрузку и
автозагрузку (POSIX module happens to do both dynamic loading and
autoloading), пользователь может сказать просто C<use POSIX>, чтобы получить и то и другое.

=head2 Делаем ваш модуль потокозащищенным (Making your module threadsafe)
X<threadsafe> X<thread safe>
X<module, threadsafe> X<module, thread safe>
X<CLONE> X<CLONE_SKIP> X<thread> X<threads> X<ithread>

Perl поддерживает тип потоков называемый интерпретатор потоков (interpreter threads)(ithreads).
Эти потоки могут использоваться явно и неявно.


Ithreads работают путем клонирования дерева данных таким образом, чтобы данные не разделялись
между различными потоками. Эти потоки могут быть использованы с помощью модуля C<threads>
 или выполнив fork() на win32 (поддержка поддельной функции fork() ). Когда
 поток клонируется - все данные Perl клонируются, хотя не-Perl данные не могут
клонироваться автоматически. Perl 5.8.0 имеет поддержку специальной подпрограммы C<CLONE>.
 С C<CLONE> вы можете делать все, что вам нужно сделать,
как например обрабатывать клонированные не-Perl данные, в случае необходимости.
C<CLONE> будет вызван один раз как метод класса для каждого пакета, в котором о
определен (или геде его наследуют). Он будет вызываться в контексте нового потока,
таким образом, все изменения будут сделаны уже в новой области. В настоящее время CLONE вызывается
без параметров не считая имени вызвавшего пакета, но код не должен предполагать
что это будет оставаться без изменений, так как, вероятно, что в будущем дополнительные параметры
будут передаваться, чтобы в дать больше информации о состоянии клонирования.

Если вы хотите КЛОНИРОВАТЬ (CLONE) все объекты, вам нужно будет отслеживать изменения в
их пакетах. Это просто выполняется с помощью хэша и Scalar::Util::weaken().

Perl после 5.8.7 имеет поддержку для специальной подпрограммы C<CLONE_SKIP>.
Как и С<CLONE> C<CLONE_SKIP> вызывается один раз для каждого пакета, однако, он
вызывается непосредственно перед началом клонирования и в контексте родительского
потока. Если он возвращает значение true, то объекты этого класса не будут
клонироваться; или, скорее они будут скопированы как неблагословленные, неопределенные значения (unblessed, undef value).
Например: если в родителе есть две ссылки на один благословленный
хэш, то у ребенка вместо этого будут две ссылки на одно неопределенное скалярное значение.
Это обеспечивает простой механизм для создания потокозащищенного(threadsafe) модуля; просто добавьте
C<sub CLONE_SKIP { 1 }> в верхней части класса и C<DESTROY()> будет
теперь вызываться только один раз за объект. Конечно, если дочерний поток
 требует, чтобы использовались объекты, то требуется более сложный подход.

Как С<CLONE> C<CLONE_SKIP> в настоящее время вызывается без параметров кроме
 имени вызывающего пакета, хотя это может измениться. Аналогично,
 для разрешить будущего расширения, возвращаемое значение должно быть одним значением C<0> или C<1>.

=head1 SEE ALSO

Смотрите L<perlmodlib> по вопросам общего стиля создания Perl модулей и классов,
 а также описания стандартной библиотеки и CPAN, смотрите L<Exporter> для того, чтобы узнать о тот, как работает стандартный механизм импорта/экспорта в Perl 
, L<perlootut> and L<perlobj> для подробной информации о создании классов, 
L<perlobj> для подробнейшего справочного документа по объектам, L<perlsub> для объяснений функций и областей их действия (scoping),
и L<perlxstut> и L<perlguts> для получения дополнительной информации по написанию модулей расширения.

=head1 ПЕРЕВОДЧИК
  
=over

=item * Николай Мишин C<< <mi@ya.ru> >>

=item * Андрей Асякин C<< <asan999 at gmail.com> >>
  
=back


