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

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

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

14.08.2008 14:11:42
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);
20
15.07.2009 04:33:27
Вы просто хотите eval {$ x-> isa ($ type)}; Если это не объект, вы вернетесь false. Если это неправильный тип, вы получаете false, а если это правильный тип, вы получаете true. :)
brian d foy 28.11.2008 18:36:14

И моя первая мысль об этом была: «Объекты в Perl всегда хэш-ссылки, так что за хак?»

Но Scalar :: Util :: reftype - это ответ. Спасибо, что поставили вопрос здесь.

Вот фрагмент кода, чтобы доказать это .. (на случай, если он кому-нибудь пригодится).

$> perl -e 'использовать строгий; использовать предупреждения «все»;
            мой $ х = [1]; благослови ($ x, "ABC :: Def");
            использовать Data :: Dumper; распечатать самосвал $ x;
            печать ref ($ x). "\ П";
            используйте Scalar :: Util "reftype"; выведите reftype ($ x). "\ П" ' `

Вывод:

$ VAR1 = благослови ([
                 1
               ], 'ABC :: Def');
ABC :: Def
ARRAY
2
1.11.2018 13:56:01
Объекты часто реализуются как хеш-ссылки, но это не является обязательным требованием. Объект может быть любого ссылочного типа.
brian d foy 28.11.2008 18:34:36

Вы, вероятно, не должны этого делать. Базовый тип объекта - это деталь реализации, с которой не стоит связываться. Зачем вам это знать?

6
5.09.2008 12:18:09
Договорились, и я знал, что кто-то сделает этот комментарий. Я действительно нуждался в этом только при попытке выяснить структуру, которую создавал модуль, чтобы я мог изменить модуль. Я хотел удалить определенный ключ из любых хэшей в структуре, потому что они содержали сырой JPEG.
Ryan Olson 9.09.2008 11:53:05
Позже я обнаружил, что могу использовать Data :: Dumper :: sortkeys для фильтрации этих данных, чтобы Data :: Dumper не создавал мегабайт двоичного вывода.
Ryan Olson 9.09.2008 11:55:26