Как определить тип благословенной ссылки в Perl?
Вопрос
В Perl объект — это просто ссылка на любой из базовых типов данных Perl, включенных в определенный класс.Когда вы используете функцию ref() для неблагословенной ссылки, вам сообщают, на какой тип данных указывает ссылка.Однако когда вы вызываете ref() для благословленной ссылки, вам возвращается имя пакета, в который была благословлена ссылка.
Я хочу знать фактический основной тип благословенной ссылки.Как я могу это определить?
Решение
Scalar::Util::reftype()
это самое чистое решение.А Scalar::Util
Модуль был добавлен в ядро Perl в версии 5.7, но доступен для более старых версий (5.004 или новее) из CPAN.
Вы также можете проверить с помощью UNIVERSAL::isa()
:
$x->isa('HASH') # if $x is known to be an object
UNIVERSAL::isa($x, 'HASH') # if $x might not be an object or reference
Очевидно, вам также придется проверить ARRAY
и SCALAR
типы.Модуль UNIVERSAL (который служит базовым классом для всех объектов) является частью ядра начиная с Perl 5.003.
Другой способ — простой, но немного грязный — преобразовать ссылку в строку.Предполагая, что класс не перегрузил строковую обработку, вы получите что-то вроде Class=HASH(0x1234ABCD)
, который вы можете проанализировать, чтобы извлечь базовый тип данных:
my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i);
Другие советы
Вероятно, вам не следует этого делать.Базовый тип объекта — это деталь реализации, с которой не следует связываться.Зачем вам это знать?
И моя первая мысль по этому поводу была:«Объекты в Perl всегда являются хэш-ссылками, так в чем же хак?»
Но Scalar::Util::reftype — это ответ.Спасибо, что задали вопрос здесь.
Вот фрагмент кода, подтверждающий это.(на случай, если это кому-нибудь пригодится).
$> perl -e 'use strict; use warnings "all"; my $x = [1]; bless ($x, "ABC::Def"); use Data::Dumper; print Dumper $x; print ref($x) . "\n"; use Scalar::Util "reftype"; print reftype($x) . "\n"'`
Выход:
$VAR1 = bless( [ 1 ], 'ABC::Def' ); ABC::Def ARRAY