Spec-Zone.ru › Perl 5.28

УНИВЕРСАЛЬНЫЙ

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНОПСИС
  • ОПИСАНИЕ
  • ПРЕДУПРЕЖДЕНИЯ
  • ЭКСПОРТ

ИМЯ

УНИВЕРСАЛЬНЫЙ — базовый класс для ВСЕХ классов (благословлённые ссылки)

СИНОПСИС

$is_io    = $fd->isa("IO::Handle");
$is_io    = Class->isa("IO::Handle");

$does_log = $obj->DOES("Logger");
$does_log = Class->DOES("Logger");

$sub      = $obj->can("print");
$sub      = Class->can("print");

$sub      = eval { $ref->can("fandango") };
$ver      = $obj->VERSION;

# but never do this!
$is_io    = UNIVERSAL::isa($fd, "IO::Handle");
$sub      = UNIVERSAL::can($obj, "print");

ОПИСАНИЕ

UNIVERSAL является базовым классом, от которого наследуются все благословлённые ссылки. См. perlobj.

UNIVERSAL предоставляет следующие методы:

$obj->isa( TYPE )
CLASS->isa( TYPE )
eval { VAL->isa( TYPE ) }

Где

TYPE

— имя пакета

$obj

— благословлённая ссылка или имя пакета

CLASS

— имя пакета

VAL

— любое из вышеперечисленного или неблагословлённая ссылка

При использовании как методами экземпляра или класса ($obj->isa( TYPE )), isa возвращает истина, если $obj благословлён в пакет TYPE или наследуется от пакета TYPE.

При использовании как методом класса (CLASS->isa( TYPE ), иногда называемым статическим методом), isa возвращает истина, если CLASS наследуется от (или сам является) именем пакета TYPE или наследуется от пакета TYPE.

Если вы не уверены, что у вас (случай VAL), оберните вызов метода в блок eval, чтобы перехватить исключение, если VAL не определено.

Если вы хотите быть уверены, что вы вызываете isa как метод, а не как класс, сначала проверьте вызываемый объект с помощью blessed из Scalar::Util:

use Scalar::Util 'blessed';

if ( blessed( $obj ) && $obj->isa("Some::Class") ) {
    ...
}
$obj->DOES( ROLE )
CLASS->DOES( ROLE )

DOES проверяет, выполняет ли объект или класс роль ROLE. Роль — это именованная группа определенного поведения (часто методы с определёнными именами и подписями), похожая на класс, но не обязательно полным классом сама по себе. Например, ведение журнала или сериализация могут быть ролями.

DOES и isa аналогичны, в том смысле, что если любое из них истинно, вы знаете, что объект или класс, на котором вы вызываете метод, может выполнить определённое поведение. Однако DOES отличается от isa тем, что ему неважно, *как* вызываемый объект выполняет операции, лишь бы он их выполнял. (isa конечно требует отношения наследования. Другие отношения включают агрегацию, делегирование и моделирование.)

По умолчанию классы в Perl выполняют только роль UNIVERSAL, а также роль всех классов в их иерархии наследования. Другими словами, по умолчанию DOES реагирует так же, как isa.

Существует взаимосвязь между ролями и классами, так как каждый класс подразумевает существование роли с тем же именем. Также существует взаимосвязь между наследованием и ролями, так как подкласс, который наследует от родительского класса, неявно выполняет все роли, которые выполняет его родитель. Таким образом, вы можете использовать DOES вместо isa безопасно, так как он вернёт истину во всех местах, где isa вернёт истину (при условии, что любые переопределённые методы DOES и isa ведут себя должным образом).

$obj->can( METHOD )
CLASS->can( METHOD )
eval { VAL->can( METHOD ) }

can проверяет, есть ли у объекта или класса метод с именем METHOD. Если есть, он возвращает ссылку на подпрограмму. Если нет, то возвращает undef. Это включает методы, унаследованные или импортированные $obj, CLASS, или VAL.

can не может знать, сможет ли объект предоставить метод через AUTOLOAD (если только класс объекта не переопределил can должным образом), поэтому значение undef не обязательно означает, что объект не сможет обработать вызов метода. Чтобы обойти это, некоторые авторы модулей используют объявление вперёд (см. perlsub) для методов, которые они будут обрабатывать через AUTOLOAD. Для таких «фиктивных» подпрограмм can всё ещё вернёт ссылку на код, которая, при вызове, обработает AUTOLOAD. Если подходящий AUTOLOAD не предоставлен, вызов кода вызовет ошибку.

Вы можете вызвать can как методом класса (статическим методом) или методом объекта.

Снова, то же правило о валидном вызываемом объекте применяется — используйте блок eval или blessed, если вам нужно быть чрезмерно осторожным.

VERSION ( [ REQUIRE ] )

VERSION вернёт значение переменной $VERSION в пакете, к которому благословлён объект. Если REQUIRE задан, он произведёт сравнение и вызовет ошибку, если версия пакета не больше или равна REQUIRE, или если $VERSION или REQUIRE не являются версией «слабого» типа (как определено модулем version).

Возвращаемое значение из VERSION фактически будет строковое представление версии объекта, использующее скаляр $VERSION пакета, который гарантированно эквивалентен, но может не совпадать с содержимым скаляра $VERSION. Если вам нужно фактическое содержимое $VERSION, используйте $CLASS::VERSION вместо этого.

VERSION может быть вызван как методом класса (статическим методом), так и методом объекта.

ПРЕДУПРЕЖДЕНИЯ

ПРИМЕЧАНИЕ: can напрямую использует внутренний код Perl для поиска методов, и isa использует очень похожую стратегию метода и кэширования. Это может привести к странным эффектам, если Perl-код динамически изменяет @ISA в любом пакете.

Вы можете добавить другие методы в класс UNIVERSAL с помощью Perl или XS-кода. Вам не нужно use UNIVERSAL для того, чтобы эти методы были доступны в вашей программе (и не следует этого делать).

ЭКСПОРТ

Нет.

Предыдущие версии этой документации предлагали использовать isa как функцию для определения типа ссылки:

$yes = UNIVERSAL::isa($h, "HASH");
$yes = UNIVERSAL::isa("Foo", "Bar");

Проблема в том, что этот код *никогда* не вызовет переопределённый метод isa в любом классе. Вместо этого используйте reftype из Scalar::Util для первого случая:

use Scalar::Util 'reftype';

$yes = reftype( $h ) eq "HASH";

и форму метода isa для второго:

$yes = Foo->isa("Bar");

© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.28.3/UNIVERSAL

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API