Модуль Perl - это отдельный компонент программного обеспечения для языка программирования Perl . Технически это особый набор соглашений для использования механизма пакетов Perl, который стал повсеместно принятым. [ обсудить ]
Модуль определяет свой исходный код как находящийся в пакете (во многом как пакет Java ), механизм Perl для определения пространств имен , например CGI или Net :: FTP или XML :: Parser ; структура файла отражает структуру пространства имен (например, исходный код для Net :: FTP находится в Net / FTP.pm ). Кроме того, модуль является эквивалентом класса в Perl, когда используется объектно-ориентированное программирование . [ обсудить ]
Набор модулей с сопроводительной документацией , сценариями сборки и обычно набором тестов составляет дистрибутив . Сообщество Perl имеет обширную библиотеку дистрибутивов, доступных для поиска и загрузки через CPAN .
Perl - это язык, допускающий множество различных стилей программирования. Разработчик может найти модуль, написанный как в процедурном стиле (например, Test :: Simple ), так и в объектно-ориентированном (например, XML :: Parser ), оба они считаются одинаково допустимыми в зависимости от того, что модуль должен делать. Модули также могут быть использованы для Mixin методов ( DBIx :: Класс ) или быть прагму ( strict.pm ) , который имеет эффект сразу же после загружается. Модули можно использовать даже для изменения синтаксиса языка. Эффект модулей Perl обычно ограничен текущей областью, в которой они были загружены.
Модули Perl обычно имеют встроенную документацию в формате Perl's Plain Old Documentation . POD мало структурирует автора. Он достаточно гибкий, чтобы его можно было использовать для написания статей, веб-страниц и даже целых книг, таких как Programming Perl . В отличие от javadoc, который специализируется на документировании классов Java . По соглашению, документация модуля обычно следует структуре страницы руководства Unix .
Язык Perl определяется единственной реализацией (именуемой «perl») и добавляется (а в редких случаях удаляется) в каждый новый выпуск. По этой причине автору модуля важно знать, какие функции они используют и какова минимально необходимая версия perl. Код на этой странице требует perl 5.6.0, который сейчас считается довольно старым.
Примеры
Ниже приведены примеры реализации « Hello, World » в различных стилях модулей. Следует понимать, что в Perl модуль не нужен; функции и код можно определять и использовать где угодно. Это просто для примера. В отличие от Java, где класс необходим всегда. Настоящая функция «Hello, World» будет записана так:
sub hello { "Привет, мир! \ n" } print hello ();
или просто напечатайте в одну строку:
print "Привет, мир! \ n" ;
Процедурный пример
Вот "Hello, World", реализованный как процедурный модуль с настраиваемой целью для приветствия, просто чтобы сделать вещи интересными. Также включен короткий сценарий, иллюстрирующий использование модуля.
hello_world.pl
#! / usr / bin / perl # Загружает модуль и импортирует любые функции в наше пространство имен # (по умолчанию "main"), экспортированные модулем. Hello :: World по умолчанию экспортирует # hello (). Экспорт обычно может контролироваться вызывающей стороной. используйте Hello :: World ;напечатать привет (); # выводит "Hello, world! \ n" print hello ( "Milky Way" ); # выводит сообщение "Привет, Млечный Путь! \ n"
Привет / World.pm
# "package" - это пространство имен, в котором находятся функциональные возможности / данные модуля. # Он определяет имя файла, если вы хотите, чтобы он был "использован" d. # Если более одного слова, это ограничивает расположение модуля.пакет Hello :: World ;# По умолчанию Perl позволяет использовать переменные без объявления # их. Это может быть удобно для коротких скриптов и однострочников. # Но в более длинном блоке кода, таком как модуль, разумно объявлять # свои переменные как для обнаружения опечаток, так и для # соответствующего ограничения их доступности извне модуля. Прагма strict # заставляет вас объявлять переменные. используйте строгий ; # Точно так же Perl по умолчанию не выдает большинство предупреждений компилятора или времени выполнения. # Более сложные сценарии, такие как большинство модулей, обычно # очень полезны для отладки. Прагма предупреждений включает необязательные предупреждения. использовать предупреждения ; # Номер версии модуля хранится в $ ModuleName :: VERSION; определенные # формы встроенного "использования" зависят от определения этой переменной.наша $ VERSION = '1.00' ;# Наследовать от модуля «Экспортер», который обрабатывает функции экспорта. # Большинство процедурных модулей используют это.использовать базу «Экспортер» ;# Когда модуль вызывается, экспортируйте по умолчанию функцию "hello" в # пространство имен используемого кода.наш @EXPORT = qw (привет) ;# Строки, начинающиеся со знака равенства, указывают на встроенную документацию POD #. Разделы POD заканчиваются директивой = cut и могут # почти свободно смешиваться с обычным кодом.= head1 ИМЯHello :: World - инкапсуляция общего выходного сообщения= head1 ОБЗОР используйте Hello :: World; напечатать привет (); распечатать привет («Млечный Путь»);= head1 ОПИСАНИЕЭто процедурный модуль, который дает вам знаменитое "Hello, world!" сообщение, и его даже можно настроить!= head2 ФункцииСледующие функции экспортируются по умолчанию= head3 привет напечатать привет (); распечатать привет ($ target);Возвращает известное приветствие. Если указан C <$ target>, он будет использован, в противном случае цель вашего приветствия - "world".= вырезать# определяем функцию hello ().к югу привет { моя цель $ = сдвиг ; $ target = 'world', если не определено $ target ; return "Привет, $ target! \ n" ; }= head1 АВТОРДжо Хакер @joehacker.org>= вырезать# Модуль Perl должен заканчиваться истинным значением, иначе считается, что он # не загружен. По соглашению это значение обычно равно 1, хотя # оно может быть любым истинным значением. Модуль может заканчиваться ложью, чтобы указать на сбой, но # это редко используется, и вместо этого он умрет () (завершится с ошибкой). 1 ;
Поскольку Hello / World.pm отсутствует в вашем пути @INC, вы должны указать. в командной строке, чтобы запустить приведенный выше пример:
perl -I. hello_world.pl
Объектно-ориентированный пример
Вот пример того же самого, сделанного в объектно-ориентированном стиле. Преимущество объектно-ориентированного модуля состоит в том, что каждый объект может быть настроен независимо от других объектов.
hello_world.pl
#! / usr / bin / perlиспользуйте Hello :: World ; мой $ hello = Hello :: World -> новый ; $ привет -> печать ; # выводит "Hello, world! \ n" $ hello -> target ( "Milky Way" ); $ привет -> печать ; # выводит сообщение "Привет, Млечный Путь! \ n"мое $ приветствие = Hello :: World -> новый ( target => "Питтсбург" ); $ приветствие -> печать ; # выводит "Hello, Pittsburgh! \ n" $ hello -> print ; # все еще печатает "Привет, Млечный Путь! \ n"
Привет / World.pm
# В Perl нет специального определения «класса». Пространство имен - это класс. пакет Hello :: World ;используйте строгий ; использовать предупреждения ; наша $ VERSION = "1.00" ;= head1 NAME Hello :: World - инкапсуляция общего выходного сообщения = head1 ОБЗОР use Hello :: World; мой $ hello = Hello :: World-> new (); $ hello-> печать; = head1 ОПИСАНИЕ Это объектно-ориентированная библиотека, которая может печатать известное «HW» сообщение. = head2 Methods = head3 new my $ hello = Hello :: World-> new (); мой $ hello = Hello :: World-> new (target => $ target); Создает экземпляр объекта, который содержит приветственное сообщение. Если задан C <$ target>, он передается в C << $ hello-> target >>. = вырезать # Конструктор объекта по соглашению называется new (). Любой метод # может создавать объект, и вы можете иметь их сколько угодно. sub новый { мой ( $ class , % args ) = @_ ; мой $ self = bless ({}, $ class ); моя $ target = существует $ args { target } ? $ args { цель } : "мир" ; $ self -> { цель } = $ цель ; return $ self ; } = head3 target my $ target = $ hello-> target; $ hello-> target ($ target); Получает и устанавливает текущую цель нашего сообщения. = вырезать к югу от целевой { моего $ самообеспечения = сдвиг ; если ( @_ ) { моя цель $ = сдвиг ; $ self -> { цель } = $ цель ; } return $ self -> { цель }; } = head3 to_string мое приветствие = $ hello-> to_string; Возвращает приветствие $ в виде строки = cut sub to_string { мой $ self = shift ; return "Привет, $ self -> {target}!" ; } = head3 print $ hello-> print; Вывод приветствия в STDOUT = cut sub print { мой $ self = shift ; print $ self -> to_string (), "\ n" ; } = head1 АВТОР Джо Хакер @joehacker.org>= вырезать 1 ;
Пакеты и пространства имен Perl
У запущенной программы Perl есть встроенное пространство имен " main
", которое является именем по умолчанию. Например, вызываемая подпрограмма Sub1
может называться Sub1()
или main::Sub1()
. В случае переменной соответствующий сигил помещается перед пространством имен; поэтому скалярная переменная $var1
также может называться $main::var1
, или даже $::var1
. Другие пространства имен могут быть созданы в любое время.
пакет Namespace1 ; $ var1 = 1 ; # создается в пространстве имен Namespace1, которое также создается, если не существует ранее нашего $ var2 = 2 ; # также создается в этом пространстве имен; наш требуемый, если применяется строгое использование my $ var3 = 3 ; # с лексической областью видимости my-declare - НЕ в любом пространстве имен, даже в основном
$ Namespace2 :: var1 = 10 ; # создается в пространстве имен Namespace2, также создается, если не существует ранее, в нашем $ Namespace2 :: var2 = 20 ; # также создается в этом пространстве имен my $ Namespace2 :: var3 = 30 ; # ошибка компиляции: объявленные мной переменные НЕ МОГУТ принадлежать пакету
Объявления пакетов применяют область действия пакета до следующего объявления пакета или до конца блока, в котором сделано объявление.
наш $ mainVar = 'a' ; пакет Sp1 ; наш $ sp1aVar = 'aa' ; print "$ main :: mainVar \ t $ sp1aVar \ n" ; # обратите внимание, что mainVar требует квалификационного пакета Sp2 ; наш $ sp2aVar = 'aaa' ; print "$ main :: mainVar \ t $ Sp1 :: sp1aVar \ t $ sp2aVar \ n" ; # обратите внимание, что mainVar и sp1aVar требуют квалификационного пакета main ; print "$ mainVar \ t $ Sp1 :: sp1aVar \ t $ Sp2 :: sp2aVar \ n" ; # обратите внимание, что sp1aVar и sp2aVar требуют квалификации$ mainVar = 'b' ; { # ПРИМЕЧАНИЕ ранее созданные пакеты и переменные пакета по-прежнему доступны package Sp1 ; наш $ sp1bVar = 'bb' ; print "$ main :: mainVar \ t $ sp1aVar \ t $ sp1bVar \ n" ; # обратите внимание, что mainVar требует квалификации { package Sp2 ; наш $ sp2bVar = 'bbb' ; print "$ main :: mainVar \ t $ Sp1 :: sp1aVar $ Sp1 :: sp1bVar \ t $ sp2aVar $ sp2bVar \ n" ; } # обратите внимание на mainVar и sp1 ... Var требуется уточняющая печать "$ main :: mainVar \ t $ sp1bVar $ sp1aVar \ t $ Sp2 :: sp2bVar $ Sp2 :: sp2aVar \ n" ; } # note package Sp1 применяется по умолчанию # main снова применяется по умолчанию; все переменные пакета по-прежнему доступны до тех пор, пока квалифицировано print "$ mainVar \ t $ Sp1 :: sp1aVar $ Sp2 :: sp2bVar \ n" ;
Пакеты и модули
Обычно пространства имен связаны с модулями; на практике обычно существует одно пространство имен для каждого модуля и наоборот, но это не предусмотрено языком. Например, «стандартный» модуль CGI.pm имеет следующее объявление вверху:
пакет CGI ;
Этот модуль и его функции обычно вызываются следующим образом:
используйте CGI ( ': standard' ); # импортирует множество функций, включая b () ... print b ( 'Hello, world' ); # выходов Hello, world
«Отсутствующая» подпрограмма может быть добавлена из пространства имен используемой программы.
sub CGI :: bi { # определение целевого пространства имен (CGI) и подменю (bi) return b ( i ( $ _ [ 0 ])); }
и вызывается, как показано ниже:
print CGI :: bi ( 'Привет, мир' ); # выходов Hello, world
Однако, хотя это технически осуществимо, это было бы сомнительной практикой программирования. С таким же успехом вы можете определить подпрограмму в вызывающем пространстве имен и вызывать ее из этого пространства имен.