Spec-Zone.ru › Perl 5.34

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

СОДЕРЖАНИЕ

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

ИМЯ

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

СИНОПСИС

$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 возвращает true, если $obj благословлён в пакет TYPE или наследуется от пакета TYPE.

Когда используется как метод класса (CLASS->isa( TYPE ), иногда называемый статическим методом), isa возвращает true, если 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, так как она вернёт true во всех местах, где isa вернёт true (при условии, что любые переопределённые 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 не предоставлен, вызов coderef вызовет ошибку.

Вы можете вызвать 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.34.0/UNIVERSAL

Spec-Zone.ru

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