Как найти какой тип объекта у меня на Perl? - PullRequest
29 голосов
/ 19 января 2010

Как мне найти тип объекта, с которым я имею дело в Perl?Я попытался использовать perl -d для входа в отладчик, но я не уверен, что делать потом.Точно так же я хотел бы получить способ легко увидеть, какие методы доступны для каждого объекта, как это можно сделать?

Ответы [ 4 ]

29 голосов
/ 19 января 2010

Стандартный способ определения типа объекта: ref или Scalar::Util::blessed. Если вы знаете объект благословен, они возвращают ту же информацию.

my $class1 = blessed( $obj );
my $class2 = ref $obj;

Но ref также вернет 'HASH' для необработанных хэшей, в то время как blessed отказывается играть в эту игру.

Что касается списка методов, то для стиля благословенного указателя объекта perl достаточно просто написать один код самостоятельно. Код ниже работает довольно хорошо для меня. Он возвращает имена функций (которые занимают «слот КОДА» с заданным именем), сопоставленных с пакетом, который их определяет.

sub class_methods { 
    use Class::ISA;
    my $obj = shift;
    return unless ref( $obj );
    my %meth_names;
    foreach my $anc ( Class::ISA::self_and_super_path( ref $obj ), 'UNIVERSAL' ) {
        my $stash = \%{"$anc\::"};
        my @funcs 
            = grep { m/^[_\p{Alpha}]/                # begins with _ or alpha
                   && !exists $meth_names{$_}        # no clobbering
                   &&  defined *{$stash->{$_}}{CODE} # has a filled CODE slot
                   } keys %$stash
            ;
        # assign to the "hash slice", keyed by all the entries in @funcs
        # the value of $anc repeated as many times as elements in @funcs.
        @meth_names{@funcs} = ( $anc ) x @funcs;
    }
    return %meth_names;
}
  • Это будет работать и для достаточно сложных объектов, но если пакет-владелец содержит много сгенерированного кода, не очень полезно знать, в какой пакет генераторы вставили указатель кода. Значит больше, чтобы найти, какой пакет генерирует код

  • В таком случае вы могли бы получить код при запуске вашего кода, включая Data::Dumper и установку $Data::Dumper::Deparse в 1, например так: local $Data::Dumper::Deparse = 1;) и затем выводит указатель кода, например: say Dumper( $code_ref );

  • Это БЕЗ работает для допустимых методов, которые еще не созданы какими-либо AUTOLOAD методами. Если вы видите их в списке, объект может сделать больше, но что все, что он делает, вы не знаете.

  • «Базовый класс» UNIVERSAL включен, поскольку этот класс содержит поведение, используемое объектом.

Удачи.

5 голосов
/ 19 января 2010

Функция blessed из Scalar :: Util сообщит вам имя пакета любой благословенной ссылки (объекта.)

Чтобы узнать, какие методы доступны, обратитесь к документации для этого пакета. Кроме того, вы можете использовать что-то вроде Class :: MOP :: Class , чтобы создать экземпляр метакласса и получить интроспективную информацию о методах, которые он содержит.

3 голосов
/ 29 января 2010

Просто для полноты, вот очень краткое введение в отладчик.

perl -d your_program

запускает его под bugger.Вы получите контроль над первой исполняемой строкой (операторы use и тому подобное уже выполнялись на этом этапе).

's' перейдет к следующей строке.После того, как вы ввели 's', вы можете просто нажать Return, чтобы повторить его.'s' уйдет в функции / подпрограммы / методы.Либо продолжайте идти до тех пор, пока не вернетесь, либо введите команду 'r', чтобы выполнить остальную часть функции и вернуться сразу после вызова.

Если вы хотите перешагнуть подпрограммы, то есть выполнить их ивернуться без необходимости заходить и возвращаться, используйте 'n.Возврат каретки после первого «n» также продолжает выполнять «n» для вас.

Если вы знаете строку, на которой хотите остановиться, используйте команду «b» - b linenumber - для установки точки останова,затем «с», чтобы продолжить, пока не достигнете.Обратите внимание, что каждый раз, когда вы 'c' и возвращаетесь к точке останова, вы снова останавливаетесь.Используйте 'B linenumber', чтобы выключить точку останова.

Итак, давайте предположим, что вы получили что-то вроде этого:

my $obj = complex_function_returning_unknown_thing;

Отладчик только что показал вам эту строку, которая говорит "Я еще не выполнил это, но это то, что я буду делать дальше ".Введите «n» для выполнения подпрограммы, затем используйте команду «x» для просмотра объекта: «x $ obj».Если он большой, вы можете сказать «| x $ obj», который пропускает вывод через пейджер.Чтобы увидеть, какие методы есть у объекта, используйте 'm $ obj'.

В отладчике гораздо больше, но вы действительно можете использовать его для такого рода вещей - вам просто нужно увидеть типобъект, который вы получаете из некоторого кода, и выясните, какие методы у объекта, который вы получили.

Возможно, было бы более полезно 'x' обьектить объект и затем посмотреть на источник класса, в котором был объектблагословил узнать, что вы должны делать, а не то, что вы можете делать.Команда 'x' в значительной степени похожа на 'print ref ($ obj)', в любом случае, с Data :: Dumper.

0 голосов
/ 19 января 2010

Вы ищете отражение в Perl.Я только что гуглил "Perl Reflection" без кавычек, и это пришло:

http://coding.derkeiler.com/Archive/Perl/perl.beginners/2004-10/0291.html

Редактировать: И это: http://markmail.org/message/i5mzik56ry4zoxxq

Редактировать: И это: http://en.wikipedia.org/wiki/Reflection_(computer_science)#Perl

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...