Spec-Zone.ru › Perl 5.38

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

СОДЕРЖАНИЕ

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

ИМЯ

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

СИНТЕКС

my $obj_is_io    = $fd->isa("IO::Handle");
my $cls_is_io    = Class->isa("IO::Handle");

my $obj_does_log = $obj->DOES("Logger");
my $cls_does_log = Class->DOES("Logger");

my $obj_sub      = $obj->can("print");
my $cls_sub      = Class->can("print");

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

# but never do this!
my $is_io        = UNIVERSAL::isa($fd, "IO::Handle");
my $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, так как оно вернёт true во всех местах, где вернёт true 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 не предоставлен, вызов 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–2023 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.38.0/UNIVERSAL

Spec-Zone.ru

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