Spec-Zone.ru › Perl 5.32

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

СОДЕРЖАНИЕ

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

НАЗВАНИЕ

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

СИНТЕКС

$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.32.0/UNIVERSAL

Spec-Zone.ru

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