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

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

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

3 ответа

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

    But, Scalar::Util::reftype is the answer. Спасибо, что задал вопрос.

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

    $> perl-e 'использовать strict; использовать предупреждения" all";
     my $x = [1]; bless ($x, " ABC:: Def");
     использовать данные:: Dumper; print Dumper $x;
     печать ref ($x). "\северный";
     используйте Scalar:: Util "reftype"; print reftype($x) . "\северный`'"
    

    Выход:

    $ VAR1 = bless( [
     1
     ], 'ABC:: Def' );
    ABC:: Def
    МАТРИЦА
    
  2. Тебе, наверное, не стоит этого делать. Базовый тип объекта-это детали реализации, с которыми не стоит связываться. Зачем вам это знать?

  3. Scalar::Util::reftype() самое чистое решение. Scalar::UtilМодуль был добавлен в Perl core в версии 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типы. Универсальный модуль (который служит базовым классом для всех объектов) является частью ядра с Perl 5.003.

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

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