2008-08-14 2 views
18

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

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

ответ

18

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.

Другой способ - легкий, но немного грязный - это подкрепить ссылку. Если предположить, что класс не перегружена stringification вы получите обратно что-то напоминающее Class=HASH(0x1234ABCD), который можно разобрать, чтобы извлечь базовый тип данных:

my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i); 
2

И моя первая мысль об этом была: «Объекты в 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 
+3

Объекты часто реализуется как хэш-ссылки, но это не является обязательным требованием. Объектом может быть любой ссылочный тип. – 2008-11-28 18:34:36

6

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

+0

Согласен, и я знал, что кто-нибудь сделает этот комментарий. Я действительно нуждался только в этом, пытаясь выяснить структуру, которую создавал модуль, чтобы я мог модифицировать модуль. Я хотел удалить конкретный ключ из любых хэшей в структуре, потому что они содержали необработанный JPEG. – 2008-09-09 11:53:05

+2

Позже я обнаружил, что я могу использовать Data :: Dumper :: sortkeys для фильтрации этих данных, чтобы Data :: Dumper не производил мегабайты двоичного вывода. – 2008-09-09 11:55:26

Смежные вопросы