Как я могу определить тип благословенной ссылки в Perl?

В Perl объект - это просто ссылка на любой из основных типов данных Perl, которые были добавлены в конкретный класс. Когда вы используете функцию ref () для неблаговидной ссылки, вам сообщают, на какой тип данных она указывает. Однако, когда вы вызываете ref () для благословенной ссылки, вам возвращается имя пакета, в который эта ссылка была благословлена.

Я хочу знать реальный основной тип благословенной ссылки. Как я могу это определить?

Ответов (3)

Решение

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 'использовать строго; используйте предупреждения «все»;
            мой $ x = [1]; bless ($ x, "ABC :: Def");
            используйте Data :: Dumper; print Dumper $ x;
            напечатать ref ($ x). "\ п";
            используйте Scalar :: Util "reftype"; напечатать reftype ($ x). "\ п" '`

Выход:

$ VAR1 = благослови ([
                 1
               ], 'ABC :: Def');
ABC :: Def
МНОЖЕСТВО