Существует ли инструмент для извлечения всей переменной, модуля и имен функций из файла модуля Perl?

Всегда лучше измерить вещи. В следующем коде, под g ++, использование кодированной идентификации типа руки, кажется, приблизительно в три раза быстрее, чем RTTI. Я уверен, что более реалистическая рука кодировала implementtaion, который использующие строки вместо символов будут медленнее, принося синхронизациям близко друг к другу..

#include <iostream>
using namespace std;

struct Base {
    virtual ~Base() {}
    virtual char Type() const = 0;
};

struct A : public Base {
    char Type() const {
        return 'A';
    }
};

struct B : public Base {;
    char Type() const {
        return 'B';
    }
};

int main() {
    Base * bp = new A;
    int n = 0;
    for ( int i = 0; i < 10000000; i++ ) {
#ifdef RTTI
        if ( A * a = dynamic_cast <A*> ( bp ) ) {
            n++;
        }
#else
        if ( bp->Type() == 'A' ) {
            A * a = static_cast <A*>(bp);
            n++;
        }
#endif
    }
    cout << n << endl;
}
6
задан romandas 27 August 2009 в 20:40
поделиться

6 ответов

Ознакомьтесь с новым, но хорошо рекомендуемым Class :: Sniff .

Из документации:

use Class::Sniff;
my $sniff = Class::Sniff->new({class => 'Some::class'});

my $num_methods = $sniff->methods;
my $num_classes = $sniff->classes;
my @methods     = $sniff->methods;
my @classes     = $sniff->classes;

{
  my $graph    = $sniff->graph;   # Graph::Easy
  my $graphviz = $graph->as_graphviz();

  open my $DOT, '|dot -Tpng -o graph.png' or die("Cannot open pipe to dot: $!");
  print $DOT $graphviz;
}

print $sniff->to_string;
my @unreachable = $sniff->unreachable;
foreach my $method (@unreachable) {
    print "$method\n";
}

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

10
ответ дан 8 December 2019 в 02:53
поделиться

Если я правильно понимаю, вы ищете инструмент для просмотра исходного кода Perl. Я собираюсь предложить PPI .

Вот пример, сделанный из документации:

#!/usr/bin/perl

use strict;
use warnings;

use PPI::Document;
use HTML::Template;

my $Module = PPI::Document->new( $INC{'HTML/Template.pm'} );

my $sub_nodes = $Module->find(
    sub { $_[1]->isa('PPI::Statement::Sub') and $_[1]->name }
);

my @sub_names = map { $_->name } @$sub_nodes;

use Data::Dumper;
print Dumper \@sub_names;

Обратите внимание, что это будет выводить:

     ...
     'new',
     'new',
     'new',
     'output',
     'new',
     'new',
     'new',
     'new',
     'new',
     ...

, потому что несколько классов определены в HTML / Template.pm . Очевидно, что менее наивный подход будет работать с деревом PDOM иерархическим способом.

8
ответ дан 8 December 2019 в 02:53
поделиться

Другой доступный инструмент CPAN - Class :: Inspector

use Class::Inspector;

# Is a class installed and/or loaded
Class::Inspector->installed( 'Foo::Class' );
Class::Inspector->loaded( 'Foo::Class' );

# Filename related information
Class::Inspector->filename( 'Foo::Class' );
Class::Inspector->resolved_filename( 'Foo::Class' );

# Get subroutine related information
Class::Inspector->functions( 'Foo::Class' );
Class::Inspector->function_refs( 'Foo::Class' );
Class::Inspector->function_exists( 'Foo::Class', 'bar' );
Class::Inspector->methods( 'Foo::Class', 'full', 'public' );

# Find all loaded subclasses or something
Class::Inspector->subclasses( 'Foo::Class' );

Это даст вам результаты, аналогичные Class :: Sniff; возможно, вам все равно придется выполнить некоторую обработку самостоятельно.

7
ответ дан 8 December 2019 в 02:53
поделиться

На этот вопрос есть ответы получше, но они не публикуются, поэтому я заявлю, что это самое быстрое оружие на Западе, и опубликую «быстрое исправление».

Такой инструмент действительно существует и встроен в Perl. Вы можете получить доступ к таблице символов для любого пространства имен, используя специальную хеш-переменную. Чтобы получить доступ к пространству имен main (по умолчанию):

for(keys %main::) { # alternatively %::
  print "$_\n";
}

Если ваш пакет называется My / Package.pm и, таким образом, находится в пространстве имен My :: Package , вы должны измените % main :: на % My :: Package :: для достижения того же эффекта. См. Запись perldoc perlmod в таблицах символов - они объясняют это и перечисляют несколько альтернатив, которые могут быть лучше или, по крайней мере, помогут вам начать поиск подходящего модуля для работы (что '

3
ответ дан 8 December 2019 в 02:53
поделиться

Если вы хотите сделать это без выполнения какого-либо анализируемого кода, это довольно легко сделать с PPI . Посмотрите мой Module :: Use :: Extract ; этот короткий фрагмент кода показывает вам, как извлечь любой элемент, который вы хотите, из PerlDOM PPI.

Если вы хотите сделать это с помощью кода, который вы уже скомпилировали, другие предложения в ответах лучше.

3
ответ дан 8 December 2019 в 02:53
поделиться

I found a pretty good answer to what I was looking for in this column by Randal Schwartz. He demonstrated using the B::Xref module to extract exactly the information I was looking for. Just replacing the evaluated one-liner he used with the module's filename worked like a champ, and apparently B::Xref comes with ActiveState Perl, so I didn't need any additional modules.

perl -MO=Xref module.pm 
1
ответ дан 8 December 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: