УНИВЕРСАЛЬНЫЙ
СОДЕРЖАНИЕ
ИМЯ
УНИВЕРСАЛЬНЫЙ — базовый класс для ВСЕХ классов (объектные ссылки)
СИНТЕКС
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 во всех местах, где вернёт trueisa(при условии, что любые переопределённые методы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