Это команда perlobj, которую можно запустить в бесплатном хостинг-провайдере OnWorks, используя одну из наших многочисленных бесплатных онлайн-рабочих станций, таких как Ubuntu Online, Fedora Online, онлайн-эмулятор Windows или онлайн-эмулятор MAC OS.
ПРОГРАММА:
ИМЯ
perlobj - Ссылка на объект Perl
ОПИСАНИЕ
Этот документ предоставляет справочник по функциям объектной ориентации Perl. Если ты
ищите введение в объектно-ориентированное программирование на Perl, смотрите perlootut.
Чтобы понять объекты Perl, вам сначала нужно понять ссылки в Perl. Видеть
perlref для подробностей.
Этот документ описывает все объектно-ориентированные (OO) возможности Perl с нуля. Если
вы просто хотите написать собственный объектно-ориентированный код, вы, вероятно,
лучше обслуживается с помощью одной из объектных систем из CPAN, описанных в perlootut.
Если вы хотите написать свою собственную объектную систему или вам нужно поддерживать код, который
реализует объекты с нуля, тогда этот документ поможет вам понять, как именно
Perl занимается объектной ориентацией.
Есть несколько основных принципов, определяющих объектно-ориентированный Perl:
1. Объект - это просто структура данных, которая знает, к какому классу он принадлежит.
2. Класс - это просто пакет. Класс предоставляет методы, которые должны работать с
объекты.
3. Метод - это просто подпрограмма, которая ожидает ссылку на объект (или пакет
name, для методов класса) в качестве первого аргумента.
Давайте подробно рассмотрим каждый из этих принципов.
An объект is Просто a Данные Структура
В отличие от многих других языков, поддерживающих объектную ориентацию, Perl не предоставляет никаких
специальный синтаксис для построения объекта. Объекты - это просто структуры данных Perl
(хеши, массивы, скаляры, дескрипторы файлов и т. д.), которые были явно связаны с
конкретный класс.
Эта явная ассоциация создается встроенной функцией "благословения", которая обычно
используется в конструктор подпрограмма класса.
Вот простой конструктор:
пакет File;
новый {
мой $ class = shift;
return bless {}, $ class;
}
В названии «новый» нет ничего особенного. Мы могли бы назвать наш конструктор как-нибудь иначе:
пакет File;
дополнительная нагрузка {
мой $ class = shift;
return bless {}, $ class;
}
Современное соглашение для объектно-ориентированных модулей - всегда использовать «новый» в качестве имени для
конструктор, но в этом нет необходимости. Любая подпрограмма, которая благословляет данные
структура в класс является допустимым конструктором в Perl.
В предыдущих примерах код "{}" создает ссылку на пустой анонимный хэш.
Затем функция "bless" берет эту ссылку и связывает хэш с классом в
$ класс. В простейшем случае переменная $ class будет содержать строку
"Файл".
Мы также можем использовать переменную для хранения ссылки на структуру данных, которая
благословлен как наш объект:
новый {
мой $ class = shift;
мой $ self = {};
благослови $ self, $ class;
return $ self;
}
После того, как мы благословили хеш, на который ссылается $ self, мы можем начать вызывать для него методы. Этот
полезно, если вы хотите поместить инициализацию объекта в отдельный отдельный метод:
новый {
мой $ class = shift;
мой $ self = {};
благослови $ self, $ class;
$ self -> _ initialize ();
return $ self;
}
Поскольку объект также является хешем, вы можете рассматривать его как единое целое, используя его для хранения данных.
связанный с объектом. Обычно код внутри класса может рассматривать хэш как
доступная структура данных, в то время как код вне класса всегда должен рассматривать объект как
непрозрачный. Это называется инкапсуляции. Инкапсуляция означает, что пользователь объекта
не надо знать, как это реализовано. Пользователь просто вызывает задокументированные методы на
объект.
Обратите внимание, однако, что (в отличие от большинства других объектно-ориентированных языков) Perl не гарантирует и не применяет
инкапсуляция любым способом. Если вы хотите, чтобы объекты действительно be непрозрачный нужно оформить
для этого сами. Это можно сделать разными способами, в том числе с помощью "Inside-Out"
объекты »или модули из CPAN.
Объекты Находятся Благословенный; Переменные Находятся Не
Когда мы что-то благословляем, мы не благословляем переменную, содержащую ссылку на
эту вещь, и мы не благословляем ссылку, которую хранит переменная; мы благословляем
вещь, на которую ссылается переменная (иногда известная как референт). Это лучше всего
продемонстрировано с помощью этого кода:
используйте Scalar :: Util 'blessed';
мой $ foo = {};
мой $ bar = $ foo;
благослови, $ foo, 'Класс';
print blessed ($ bar) // 'не благословлен'; # отпечаток "Класс"
$ bar = "другое значение";
print blessed ($ bar) // 'не благословлен'; # отпечаток "не благословен"
Когда мы вызываем «благословение» для переменной, мы фактически благословляем базовую структуру данных.
на которую ссылается переменная. Мы не благословляем ни саму ссылку, ни переменную.
который содержит эту ссылку. Вот почему второй вызов "blessed ($ bar)" возвращается.
ложный. В этот момент $ bar больше не хранит ссылку на объект.
Иногда вы можете увидеть в старых книгах или документации упоминание «благословение ссылки» или
описывать объект как «благословенную ссылку», но это неверно. Это не ссылка
это благословлено как объект; это то, к чему относится ссылка (т.е. референт).
A Класс is Просто a Упаковка
Perl не предоставляет никакого специального синтаксиса для определений классов. Пакет - это просто
пространство имен, содержащее переменные и подпрограммы. Единственная разница в том, что в классе
подпрограммы могут ожидать ссылку на объект или имя класса в качестве первого
аргумент. Это чисто условное обозначение, поэтому класс может содержать как методы, так и
подпрограммы, которые не работать с объектом или классом.
Каждый пакет содержит специальный массив с именем @ISA. Массив @ISA содержит список таких
родительские классы class, если таковые имеются. Этот массив исследуется, когда Perl выполняет разрешение метода,
о котором мы поговорим позже.
Можно вручную установить @ISA, и вы можете увидеть это в более старом коде Perl. Намного старше
код также использует базовую директиву. Для нового кода мы рекомендуем использовать родительскую прагму
заявить своим родителям. Эта прагма позаботится о настройке @ISA. Он также загрузит
родительские классы и убедитесь, что пакет не наследуется от самого себя.
Независимо от того, установлены ли родительские классы, переменная пакета @ISA будет содержать список
эти родители. Это просто список скаляров, каждый из которых представляет собой строку,
соответствует названию пакета.
Все классы неявно наследуются от класса UNIVERSAL. УНИВЕРСАЛЬНЫЙ класс
реализован ядром Perl и предоставляет несколько методов по умолчанию, таких как "isa ()",
«can ()» и «ВЕРСИЯ ()». Класс «УНИВЕРСАЛЬНЫЙ» будет никогда появляются в @ISA пакета
Переменная.
Perl Важно обеспечивает наследование методов как встроенную функцию. Наследование атрибутов
оставил класс для реализации. См. Подробности в разделе «Инструменты записи».
A Способ доставки is Просто a подпрограмма
Perl не предоставляет никакого специального синтаксиса для определения метода. Метод - это просто
обычная подпрограмма и объявляется с помощью "sub". Особенность метода заключается в том, что он
ожидает получить в качестве первого аргумента либо объект, либо имя класса.
Perl приносит предоставить специальный синтаксис для вызова метода, оператор "->". Мы накроем
об этом подробнее позже.
Большинство методов, которые вы пишете, будут работать с объектами:
дополнительное сохранение {
мой $ self = shift;
откройте мой $ fh, '>', $ self-> path () или die $ !;
напечатайте {$ fh} $ self-> data () или die $ !;
закрой $ fh or die $ !;
}
Способ доставки Вызов
Вызов метода объекта записывается как «$ объект-> метод».
Левая часть оператора вызова метода (или стрелки) - это объект (или класс
name), а справа - имя метода.
мой $ pod = Файл-> новый ('perlobj.pod', $ data);
$ pod-> сохранить ();
Синтаксис «->» также используется при разыменовании ссылки. Похоже то же самое
оператор, но это две разные операции.
Когда вы вызываете метод, объект слева от стрелки передается как первый
аргумент метода. Это означает, что когда мы вызываем «Critter-> new ()», метод «new ()»
получает строку «Critter» в качестве первого аргумента. Когда мы вызываем "$ fred-> speak ()",
Переменная $ fred передается как первый аргумент в "speak ()".
Как и в случае любой подпрограммы Perl, все аргументы, переданные в @_, являются псевдонимами для
оригинальный аргумент. Сюда входит и сам объект. Если вы назначите $ _ [0] напрямую, вы
изменит содержимое переменной, содержащей ссылку на объект. Мы
рекомендую не делать этого, если вы точно не знаете, что делаете.
Perl знает, в каком пакете находится метод, глядя на левую часть стрелки. Если
левая часть - это имя пакета, он ищет метод в этом пакете. Если слева
сторона - это объект, тогда Perl ищет метод в пакете, который есть у объекта.
благословил.
Если левая часть не является ни именем пакета, ни объектом, тогда вызов метода будет
вызывает ошибку, но дополнительные нюансы см. в разделе «Варианты вызова методов».
наследование
Мы уже говорили о специальном массиве @ISA и родительской прагме.
Когда класс наследуется от другого класса, любые методы, определенные в родительском классе, являются
доступный для дочернего класса. Если вы попытаетесь вызвать метод объекта, который не
определенный в своем собственном классе, Perl также будет искать этот метод в любых родительских классах, которые он может
иметь.
пакет File :: MP3;
использовать родительский файл; # устанавливает @File :: MP3 :: ISA = ('Файл');
мой $ mp3 = File :: MP3-> new ('Andvari.mp3', $ data);
$ mp3-> сохранить ();
Поскольку мы не определяли метод save () в классе File :: MP3, Perl будет рассматривать
Родительские классы класса "File :: MP3" должны найти метод "save ()". Если Perl не может найти
"save ()" в любом месте иерархии наследования, он умрет.
В этом случае он находит метод save () в классе File. Обратите внимание, что объект прошел
to "save ()" в этом случае по-прежнему является объектом "File :: MP3", даже если метод находится в
класс "Файл".
Мы можем переопределить родительский метод в дочернем классе. Когда мы это сделаем, мы все равно сможем вызвать
метод родительского класса с псевдоклассом "SUPER".
дополнительное сохранение {
мой $ self = shift;
скажите "Приготовьтесь рок";
$ self-> СУПЕР :: сохранить ();
}
Модификатор "SUPER" может Важно использоваться для вызовов методов. Вы не можете использовать его для обычных
вызовы подпрограмм или методы класса:
СУПЕР :: сохранить ($ вещь); # FAIL: ищет sub save () в пакете SUPER
СУПЕР-> сохранить ($ вещь); # FAIL: ищет метод save () в классе
# СУПЕР
$ вещь-> СУПЕР :: сохранить (); # Хорошо: ищет метод save () в родительском элементе
# класс
Как СУПЕР is Постановили
Псевдокласс "SUPER" определяется из пакета, в котором выполняется вызов. это
разрешается на основе класса объекта. Это важно, потому что позволяет методам
разные уровни внутри иерархии глубокого наследования, каждый правильно называет свои соответствующие
родительские методы.
пакет А;
новый {
вернуть благословение {}, сдвиг;
}
sub Speak {
мой $ self = shift;
скажите «А»;
}
пакет B;
используйте parent -norequire, 'A';
sub Speak {
мой $ self = shift;
$ self-> СУПЕР :: говори ();
скажите "B";
}
пакет C;
используйте parent -norequire, 'B';
sub Speak {
мой $ self = shift;
$ self-> СУПЕР :: говори ();
скажите "C";
}
мой $ c = C-> новый ();
$ c-> говорите ();
В этом примере мы получим следующий результат:
A
B
C
Это демонстрирует, как разрешается "СУПЕР". Несмотря на то, что объект благословлен на "C"
class, метод "speak ()" в классе "B" по-прежнему может вызывать "SUPER :: Speak ()" и ожидать этого.
чтобы правильно искать в родительском классе «B» (т. е. в классе, в котором находится вызов метода), а не в
родительский класс «C» (т. е. класс, к которому принадлежит объект).
В редких случаях это решение на основе пакета может быть проблемой. Если вы скопируете
подпрограммы из одного пакета в другой, разрешение "SUPER" будет выполнено на основе
оригинальная упаковка.
Многочисленные наследование
Множественное наследование часто указывает на проблему дизайна, но Perl всегда дает вам достаточно
веревка, на которой можно повеситься, если вы попросите об этом.
Чтобы объявить несколько родителей, вам просто нужно передать несколько имен классов, чтобы «использовать родительский»:
пакет MultiChild;
используйте родительский 'Parent1', 'Parent2';
Способ доставки Разрешение Оформить заказ
Порядок разрешения методов имеет значение только в случае множественного наследования. В случае
одинарное наследование, Perl просто просматривает цепочку наследования, чтобы найти метод:
бабушка или дедушка
|
Родитель
|
детей,
Если мы вызываем метод для объекта «Дочерний», а этот метод не определен в «Дочернем»
класс, Perl будет искать этот метод в родительском классе, а затем, при необходимости, в
"Дедушка" класс.
Если Perl не может найти метод ни в одном из этих классов, он умрет с сообщением об ошибке.
Когда у класса несколько родителей, порядок поиска методов становится более сложным.
По умолчанию Perl выполняет поиск метода слева направо в глубину. Это значит это
начинается с первого родителя в массиве @ISA, а затем выполняет поиск всех его родителей,
бабушек и дедушек и т. д. Если не удается найти метод, он переходит к следующему родителю в
массив @ISA исходного класса и поиск оттуда.
ОбщийОтличныйВеликийРодитель
/\
По отцовской линии дедушка по материнской линии
\ /
Отец мать
\ /
детей,
Итак, учитывая приведенную выше диаграмму, Perl будет искать «Дитя», «Отец», «Отец-дедушка»,
«SharedGreatGrandParent», «Мать» и, наконец, «MaternalGrandParent». Это может быть
проблема, потому что теперь мы ищем в "SharedGreatGrandParent" до мы проверили все его
производные классы (то есть до того, как мы попробовали "Mother" и "MaternalGrandparent").
Можно запросить другой порядок разрешения методов с помощью директивы mro.
пакет Ребенок;
используйте mro 'c3';
используйте родительский «Отец», «Мать»;
Эта прагма позволяет переключиться на порядок разрешения «C3». Говоря простым языком, порядок «С3»
гарантирует, что общие родительские классы никогда не будут просматриваться перед дочерними классами, поэтому Perl будет
теперь ищите: «Ребенок», «Отец», «Отец по отцовской линии», «Мать», «Родитель по материнской линии» и
наконец "SharedGreatGrandParent". Однако обратите внимание, что это не поиск в ширину:
Все "отцовские" предки (кроме общего предка) ищутся перед любым из
Считаются "материнскими" предками.
Порядок C3 также позволяет вам вызывать методы в родственных классах со «следующим» псевдоклассом.
См. Документацию по mro для получения дополнительных сведений об этой функции.
Способ доставки Разрешение Кэширование
Когда Perl ищет метод, он кэширует поиск, так что будущие вызовы метода
не нужно искать его снова. Изменение родительского класса класса или добавление подпрограмм
к классу сделает недействительным кеш для этого класса.
Прагма mro предоставляет некоторые функции для непосредственного управления кешем методов.
Writing Конструкторы
Как мы упоминали ранее, Perl не предоставляет специального синтаксиса конструктора. Это означает, что
класс должен реализовывать свой собственный конструктор. Конструктор - это просто метод класса, который
возвращает ссылку на новый объект.
Конструктор также может принимать дополнительные параметры, определяющие объект. Давай напишем
реальный конструктор для класса File, который мы использовали ранее:
пакет File;
новый {
мой $ class = shift;
мой ($ путь, $ данные) = @_;
my $ self = bless {
путь => $ путь,
data => $ data,
}, $ class;
return $ self;
}
Как видите, мы сохранили путь и данные файла в самом объекте. Помните, под
капюшон, этот объект по-прежнему остается всего лишь хешем. Позже мы напишем аксессоры для управления
эти данные.
Для нашего класса File :: MP3 мы можем проверить, что указанный нам путь заканчивается на
".mp3":
пакет File :: MP3;
новый {
мой $ class = shift;
мой ($ путь, $ данные) = @_;
die "Вы не можете создать File :: MP3 без расширения mp3 \ n"
если только $ path = ~ /\.mp3\z/;
вернуть $ class-> SUPER :: new (@_);
}
Этот конструктор позволяет своему родительскому классу выполнять фактическое создание объекта.
Атрибуты
Атрибут - это часть данных, принадлежащая определенному объекту. В отличие от большинства объект-
ориентированных языков, Perl не предоставляет специального синтаксиса или поддержки для объявления и
манипулирование атрибутами.
Атрибуты часто хранятся в самом объекте. Например, если объект
анонимный хеш, мы можем сохранить значения атрибутов в хеш-коде, используя имя атрибута как
ключ.
Хотя можно напрямую ссылаться на эти хеш-ключи вне класса, это
считается лучшей практикой заключать весь доступ к атрибуту с помощью методов доступа.
Это дает несколько преимуществ. Аксессоры упрощают изменение реализации
объект позже, все еще сохраняя исходный API.
Аксессор позволяет добавлять дополнительный код для доступа к атрибутам. Например, вы могли
примените значение по умолчанию к атрибуту, который не был установлен в конструкторе, или вы можете проверить
что новое значение атрибута допустимо.
Наконец, использование аксессоров значительно упрощает наследование. Подклассы могут использовать аксессоры
вместо того, чтобы знать, как родительский класс реализован внутри.
Writing Аксессоры
Как и в случае с конструкторами, Perl не предоставляет специального синтаксиса объявления средств доступа, поэтому классы
должны предоставлять явно написанные методы доступа. Есть два распространенных типа
аксессоры, только для чтения и чтения-записи.
Простой метод доступа только для чтения просто получает значение одного атрибута:
подпуть {
мой $ self = shift;
return $ self -> {путь};
}
Аксессор чтения-записи позволит вызывающей стороне как установить значение, так и получить его:
подпуть {
мой $ self = shift;
если (@_) {
$ self -> {путь} = сдвиг;
}
return $ self -> {путь};
}
An В стороне О нас Smarter и безопаснее Code
Конструктор и аксессуары у нас не очень умные. Они не проверяют, что путь $
определены, и они не проверяют, что $ path является допустимым путем в файловой системе.
Выполнение этих проверок вручную может быстро стать утомительным. Написание кучи аксессуаров с помощью
рука также невероятно утомительна. На CPAN есть много модулей, которые могут вам помочь
писать более безопасный и лаконичный код, включая модули, которые мы рекомендуем в perlootut.
Способ доставки Позвонить Вариации
Perl поддерживает несколько других способов вызова методов помимо использования "$ object-> method ()"
мы видели до сих пор.
Способ доставки Названия as Струны
Perl позволяет использовать в качестве имени метода скалярную переменную, содержащую строку:
мой $ file = File-> new ($ path, $ data);
мой $ method = 'сохранить';
$ файл -> $ method ();
Это работает точно так же, как вызов "$ file-> save ()". Это может быть очень полезно для написания
динамический код. Например, он позволяет передать имя метода, который будет вызываться в качестве параметра.
к другому методу.
Класс Названия as Струны
Perl также позволяет использовать в качестве имени класса скаляр, содержащий строку:
мой $ class = 'Файл';
мой $ file = $ class-> new ($ path, $ data);
Опять же, это позволяет получить очень динамичный код.
подпрограмма Рекомендации as методы
Вы также можете использовать ссылку на подпрограмму в качестве метода:
my $ sub = sub {
мой $ self = shift;
$ self-> save ();
};
$ файл -> $ sub ();
Это в точности эквивалентно записи «$ sub -> ($ file)». Вы можете увидеть эту идиому в дикой природе
в сочетании с призывом «можно»:
if (my $ meth = $ object-> can ('foo')) {
$ объект -> $ meth ();
}
Отнесение Способ доставки Позвонить
Perl также позволяет использовать разыменованную скалярную ссылку в вызове метода. Это
полный рот, поэтому давайте посмотрим на код:
$ файл -> $ {\ 'save'};
$ file -> $ {returns_scalar_ref ()};
$ file -> $ {\ (returns_scalar ())};
$ file -> $ {returns_ref_to_sub_ref ()};
Это работает, если разыменование производит строку or ссылка на подпрограмму.
Способ доставки Объявления on Файловые дескрипторы
Под капотом файловые дескрипторы Perl являются экземплярами класса «IO :: Handle» или «IO :: File».
Если у вас есть открытый дескриптор файла, вы можете вызывать для него методы. Дополнительно вы можете позвонить
методы для дескрипторов файлов "STDIN", "STDOUT" и "STDERR".
откройте мой $ fh, '>', 'путь / к / файлу';
$ fh-> autoflush ();
$ fh-> print ('содержимое');
STDOUT-> автозапуск ();
Вызов Класс методы
Поскольку Perl позволяет использовать голые слова для имен пакетов и имен подпрограмм, он
иногда неправильно интерпретирует значение слова. Например, конструкция
«Class-> new ()» можно интерпретировать как «'Class' -> new ()» или «Class () -> new ()». В
По-английски эта вторая интерпретация читается как «вызов подпрограммы с именем Класс(), затем позвони
новый () как метод возвращаемого значения Класс()". Если есть подпрограмма с именем
«Class ()» в текущем пространстве имен, Perl всегда будет интерпретировать «Class-> new ()» как
вторая альтернатива: вызов «new ()» для объекта, возвращенного вызовом «Class ()»
Вы можете заставить Perl использовать первую интерпретацию (т.е. как вызов метода в классе
названный «Класс») двумя способами. Во-первых, вы можете добавить "::" к имени класса:
Класс :: -> новый ()
Perl всегда будет интерпретировать это как вызов метода.
В качестве альтернативы вы можете указать имя класса:
'Класс' -> новый ()
Конечно, если имя класса находится в скалярном формате, Perl тоже поступит правильно:
мой $ class = 'Класс';
$ class-> новый ();
Косвенное охлаждение: объект Синтаксис
За пределами of файл обрабатывать случай, использование of этой синтаксис is обескураженный as it спутать
Perl переводчик. Увидеть ниже для больше
Perl поддерживает другой синтаксис вызова метода, называемый нотацией «косвенный объект». Этот
синтаксис называется "косвенным", потому что метод предшествует вызываемому объекту.
о.
Этот синтаксис можно использовать с любым методом класса или объекта:
my $ file = новый путь к файлу $, $ data;
сохранить $ файл;
Мы рекомендуем избегать этого синтаксиса по нескольким причинам.
Во-первых, это может сбивать с толку. В приведенном выше примере неясно, является ли "save"
метод, предоставляемый классом "File", или просто подпрограмма, которая ожидает файловый объект как
его первый аргумент.
При использовании с методами класса проблема еще хуже. Поскольку Perl допускает подпрограмму
имена должны быть записаны как голые слова, Perl должен угадать, есть ли голое слово после метода
- это имя класса или имя подпрограммы. Другими словами, Perl может разрешить синтаксис как
"Файл-> новый ($ путь, $ данные)" or "новый (файл ($ путь, $ данные))".
Для анализа этого кода Perl использует эвристику, основанную на том, какие имена пакетов он видел, какие
подпрограммы существуют в текущем пакете, какие простые слова он видел ранее, и другие
Вход. Излишне говорить, что эвристика может дать очень удивительные результаты!
Старая документация (и некоторые модули CPAN) поощряли этот синтаксис, особенно для
конструкторы, так что вы все еще можете найти его в дикой природе. Однако мы рекомендуем вам избегать
используя его в новом коде.
Вы можете заставить Perl интерпретировать голое слово как имя класса, добавив к нему "::", например
мы видели ранее:
мой $ файл = новый файл :: $ путь, $ данные;
"благословить", "благословенный", и "ref"
Как мы видели ранее, объект - это просто структура данных, которая была благословлена в класс.
через функцию «благословить». Функция bless может принимать один или два аргумента:
мой $ object = bless {}, $ class;
мой $ object = bless {};
В первой форме анонимный хеш внедряется в класс в $ class. в
во второй форме анонимный хеш добавляется в текущий пакет.
Вторая форма настоятельно не рекомендуется, потому что она нарушает способность подкласса к
повторно использовать родительский конструктор, но вы все равно можете встретить его в существующем коде.
Если вы хотите узнать, относится ли конкретный скаляр к объекту, вы можете использовать
"благословенная" функция, экспортируемая Scalar :: Util, которая поставляется с ядром Perl.
используйте Scalar :: Util 'blessed';
if (определено blessed ($ thing)) {...}
Если $ thing относится к объекту, то эта функция возвращает имя пакета,
объект был благословлен. Если $ thing не содержит ссылки на благословенный объект,
функция "blessed" возвращает undef.
Обратите внимание, что "blessed ($ thing)" также вернет false, если $ thing был благословлен в класс.
назвал "0". Это возможно, но довольно патологично. Не создавайте класс с именем «0»
если вы не знаете, что делаете.
Точно так же встроенная функция "ref" Perl обрабатывает ссылку на благословенный объект.
специально. Если вы вызываете "ref ($ thing)" и $ thing содержит ссылку на объект, он будет
вернуть имя класса, в который был благословлен объект.
Если вы просто хотите проверить, что переменная содержит ссылку на объект, мы рекомендуем
что вы используете "defined blessed ($ object)", поскольку "ref" возвращает истинные значения для всех
ссылки, а не только объекты.
В УНИВЕРСАЛЬНЫЙ Класс
Все классы автоматически наследуются от класса UNIVERSAL, встроенного в Perl.
основной. Этот класс предоставляет ряд методов, каждый из которых может быть вызван либо на
класс или объект. Вы также можете переопределить некоторые из этих методов в своем классе.
Если вы это сделаете, мы рекомендуем вам следовать встроенной семантике, описанной ниже.
isa ($ класс)
Метод "isa" возвращает правда если объект является членом класса в $ class, или
член подкласса $ class.
Если вы переопределите этот метод, он никогда не должен вызывать исключение.
ДЕЛАЕТ ($ роль)
Метод "DOES" возвращает правда если его объект утверждает, что выполняет роль $ role. От
по умолчанию это эквивалентно "isa". Этот метод предназначен для использования объектной системой.
расширения, реализующие роли, такие как «Moose» и «Role :: Tiny».
Вы также можете переопределить "DOES" прямо в ваших собственных классах. Если вы переопределите это
метод, он никогда не должен вызывать исключение.
может ($ метод)
Метод "can" проверяет, есть ли у класса или объекта, для которого он был вызван, метод
названный метод $. Это проверяет наличие метода в классе и всех его родителей. Если
существует, то возвращается ссылка на подпрограмму. Если это не так, то
"undef" возвращается.
Если ваш класс отвечает на вызовы методов через «AUTOLOAD», вы можете захотеть перегрузить «can»
чтобы вернуть ссылку на подпрограмму для методов, которые обрабатывает ваш метод «AUTOLOAD».
Если вы переопределите этот метод, он никогда не должен вызывать исключение.
ВЕРСИЯ (нужно $)
Метод «ВЕРСИЯ» возвращает номер версии класса (пакета).
Если указан аргумент $ need, он проверит, что текущая версия (как определено
переменной $ VERSION в пакете) больше или равно $ need; будет
умри, если это не так. Этот метод автоматически вызывается формой "ВЕРСИЯ"
"использования".
использовать пакет 1.2 qw (некоторые импортированные подпрограммы);
# подразумевает:
Пакет-> ВЕРСИЯ (1.2);
Мы рекомендуем вам использовать этот метод для доступа к другой версии пакета, а не
глядя прямо на $ Package :: VERSION. Пакет, который вы смотрите, мог иметь
переопределить метод "ВЕРСИЯ".
Мы также рекомендуем использовать этот метод, чтобы проверить, достаточно ли у модуля
версия. Внутренняя реализация использует модуль версии, чтобы убедиться, что
разные типы номеров версий сравниваются правильно.
АВТОЗАГРУЗКА
Если вы вызовете метод, которого нет в классе, Perl выдаст ошибку. Однако если
этот класс или любой из его родительских классов определяет метод «AUTOLOAD», который «AUTOLOAD»
вместо этого вызывается метод.
«АВТОЗАГРУЗКА» вызывается как обычный метод, и вызывающий не заметит разницы.
Какое бы значение ни возвращал ваш метод «AUTOLOAD», он возвращается вызывающей стороне.
Полное имя вызванного метода доступно в пакете $ AUTOLOAD.
global для вашего класса. Поскольку это глобальный объект, если вы хотите использовать ссылку, сделайте это без
префикс имени пакета в разделе "strict 'vars'", вам необходимо его объявить.
# XXX - ужасный способ реализации аксессоров, но он заставляет
# для простого примера.
наш $ AUTOLOAD;
sub АВТОЗАГРУЗКА {
мой $ self = shift;
# Удалить квалификатор из исходного имени метода ...
мой $ called = $ AUTOLOAD = ~ s /.* :: // r;
# Есть ли атрибут с таким именем?
die "Нет такого атрибута: $ called"
если не существует $ self -> {$ called};
# Если да, верните его ...
return $ self -> {$ called};
}
sub DESTROY {} # см. ниже
Без объявления "our $ AUTOLOAD" этот код не будет компилироваться в соответствии со строгими требованиями.
прагма.
Как говорится в комментарии, это не лучший способ реализовать аксессоры. Это медленно и слишком
умный, безусловно. Однако вы можете рассматривать это как способ предоставления средств доступа в более старом коде Perl.
См. Perlootut для рекомендаций по объектно-ориентированному кодированию на Perl.
Если в вашем классе есть метод «AUTOLOAD», мы настоятельно рекомендуем вам переопределить
"может" и в вашем классе. Ваш переопределенный метод "can" должен возвращать подпрограмму
ссылка на любой метод, на который отвечает ваш "AUTOLOAD".
деструкторы
Когда последняя ссылка на объект исчезает, объект уничтожается. Если у вас есть только
одна ссылка на объект, хранящийся в лексическом скаляре, объект уничтожается, когда это
скаляр выходит за рамки. Если вы храните объект в глобальном пакете, этот объект может не
выходят за рамки, пока программа не завершится.
Если вы хотите что-то сделать, когда объект уничтожен, вы можете определить «УНИЧТОЖЕНИЕ»
в вашем классе. Этот метод всегда будет вызываться Perl в подходящее время,
если метод не пуст.
Он вызывается так же, как и любой другой метод, с объектом в качестве первого аргумента. Оно делает
не получить никаких дополнительных аргументов. Однако переменная $ _ [0] будет доступна только для чтения в
деструктор, поэтому вы не можете присвоить ему значение.
Если ваш метод "DESTROY" выдает ошибку, эта ошибка будет проигнорирована. Это не будет отправлено
в "STDERR", и это не приведет к смерти программы. Однако, если ваш деструктор
выполняется внутри блока eval {}, тогда ошибка изменит значение $ @.
Поскольку методы "DESTROY" могут быть вызваны в любое время, вам следует локализовать любые глобальные
переменные, которые вы можете обновить в своем "DESTROY". В частности, если вы используете eval {}, вы
следует локализовать $ @, а если вы используете "system" или обратные кавычки, вам следует локализовать $ ?.
Если вы определите «AUTOLOAD» в своем классе, тогда Perl вызовет ваш «AUTOLOAD» для обработки
метод «РАЗРУШИТЬ». Вы можете предотвратить это, указав пустой "DESTROY", как мы это делали в
пример автозагрузки. Вы также можете проверить значение $ AUTOLOAD и вернуть его без
делает что-либо, когда вызывается для обработки "DESTROY".
Глобальный Уничтожение
Порядок уничтожения объектов при глобальном уничтожении перед программой.
выходов непредсказуемо. Это означает, что любые объекты, содержащиеся в вашем объекте, уже могут
были уничтожены. Вы должны убедиться, что содержащийся объект определен, прежде чем вызывать
метод на нем:
суб УНИЧТОЖИТЬ {
мой $ self = shift;
$ self -> {handle} -> close () если $ self -> {handle};
}
Вы можете использовать переменную "$ {^ GLOBAL_PHASE}", чтобы определить, находитесь ли вы в настоящее время в глобальном
фаза разрушения:
суб УНИЧТОЖИТЬ {
мой $ self = shift;
вернуть, если $ {^ GLOBAL_PHASE} eq 'DESTRUCT';
$ self -> {handle} -> close ();
}
Обратите внимание, что эта переменная была добавлена в Perl 5.14.0. Если вы хотите обнаружить глобальный
фаза разрушения в старых версиях Perl, вы можете использовать "Devel :: GlobalDestruction"
модуль на CPAN.
Если ваш метод "DESTROY" выдает предупреждение во время глобального уничтожения, интерпретатор Perl
добавит к предупреждению строку «во время глобального уничтожения».
Во время глобального уничтожения Perl всегда будет собирать мусор перед тем, как получить разрешение.
использованная литература. См. «PERL_DESTRUCT_LEVEL» в perlhacktips для получения дополнительной информации о глобальном
разрушение.
Без хеширования Объекты
До сих пор во всех примерах были показаны объекты, основанные на благословенном хеш-коде. Однако это
можно благословить любой тип структуры данных или референт, включая скаляры, глобусы и
подпрограммы. Вы можете увидеть подобные вещи, глядя на код в дикой природе.
Вот пример модуля в виде благословенного скаляра:
время пакета;
использовать строго;
использовать предупреждения;
новый {
мой $ class = shift;
мое $ время = время;
вернуть bless \ $ time, $ class;
}
подэпоха {
мой $ self = shift;
вернуть $ {$ self};
}
мое $ time = Время-> новый ();
напечатать $ time-> epoch ();
Вывернутый наружу объекты
В прошлом сообщество Perl экспериментировало с техникой, называемой «вывернутые наизнанку объекты».
Вывернутый наизнанку объект хранит свои данные за пределами ссылки на объект, индексированных на
уникальное свойство объекта, такое как его адрес в памяти, а не в объекте
сам. Это имеет то преимущество, что обеспечивает инкапсуляцию атрибутов объекта, поскольку
их данные не хранятся в самом объекте.
Некоторое время этот метод был популярен (и рекомендовался Дэмианом Конвеем). Perl Лучшее
Практики), но так и не получил всеобщего распространения. Модуль Object :: InsideOut на CPAN
обеспечивает комплексную реализацию этой техники, и вы можете увидеть ее или другие
вывернутые наизнанку модули в дикой природе.
Вот простой пример метода с использованием основного модуля Hash :: Util :: FieldHash.
Этот модуль был добавлен в ядро для поддержки реализации объектов наизнанку.
время пакета;
использовать строго;
использовать предупреждения;
используйте Hash :: Util :: FieldHash 'fieldhash';
fieldhash my% time_for;
новый {
мой $ class = shift;
мой $ self = bless \ (мой $ объект), $ class;
$ time_for {$ self} = время;
return $ self;
}
подэпоха {
мой $ self = shift;
вернуть $ time_for {$ self};
}
мое $ time = Время-> новый;
напечатать $ time-> эпоха;
Псевдо-хеши
Функция псевдохеширования была экспериментальной функцией, представленной в более ранних версиях Perl.
и удален в 5.10.0. Псевдохеш - это ссылка на массив, к которой можно получить доступ, используя
именованные ключи как хэш. Вы можете столкнуться с каким-то кодом в дикой природе, который его использует. Увидеть
поля прагмы для получения дополнительной информации.
Используйте perlobj в Интернете с помощью сервисов onworks.net