Spec-Zone.ru › Perl 5.36

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

СОДЕРЖАНИЕ

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

ИМЯ

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

СИНОПСИС

$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 оператор — это альтернатива, которая просто возвращает ложь в этом случае, поэтому eval не нужен.

Если вы хотите убедиться, что вызываете 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–2021 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.36.0/UNIVERSAL

Spec-Zone.ru

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