【问题标题】:How do I list available methods on a given object or package in Perl?如何在 Perl 中列出给定对象或包的可用方法?
【发布时间】:2010-10-28 23:13:21
【问题描述】:

如何在 Perl 中列出给定对象或包的可用方法?

【问题讨论】:

标签: perl introspection


【解决方案1】:

来自How to get structure and inheritance history的好回答
可以使用以下方法找到对象的类当前继承的类:

use mro          qw( );
use Scalar::Util qw( blessed );
say join ", ", @{ mro::get_linear_isa(blessed($o)) };

【讨论】:

    【解决方案2】:

    如果你有一个名为 Foo 的包,应该这样做:

    no strict 'refs';
    for(keys %Foo::) { # All the symbols in Foo's symbol table
      print "$_\n" if exists &{"Foo::$_"}; # check if symbol is method
    }
    use strict 'refs';
    

    或者,获取包Foo中所有方法的列表:

    no strict 'refs';
    my @methods = grep { defined &{"Foo::$_"} } keys %Foo::;
    use strict 'refs';
    

    【讨论】:

    • 也应该递归 @ISA 数组
    • 在 XML::Simple、Scalar::Util 和 Exporter 上进行测试显示了所有显式导出的方法。不过,递归 @ISA 应该没那么难。
    • 当然,您将很难找到自动加载的方法。
    • 为什么你很难使用自动加载的方法?我敢打赌,大多数人甚至不知道他们何时使用它们。他们调用记录在案的方法,然后发生正确的事情。
    • defined &{$_} 应该是defined &{"Foo::$_"} 否则检查将无法从不同的包中进行。
    【解决方案3】:

    在 Perl 中有(相当)很多方法可以做到这一点,因为在 Perl 中有很多方法可以做到这一点。正如有人评论的那样,自动加载的方法总是有点棘手。但是,与其采用自己的方法,我建议您查看 CPAN 上的 Class::Inspector。这将使您可以执行以下操作:

    my $methods =   Class::Inspector->methods( 'Foo::Class', 'full', 'public' );
    

    【讨论】:

    • 我终于在我的单文件脚本中包含了内联 Class::Inspector,这实际上是更简单的解决方案。谢谢。
    • 请注意 Class::Inspector 有限制。它可以查看已定义的方法,但不处理 UNIVERSAL 中的任何内容。
    • 工作正常!谢谢!
    • perldoc Class::Inspector 说:“返回对所有可用方法名称数组的引用......” - 实际上:@methods 应该是 $methods
    【解决方案4】:

    如果你有一个使用 Moose 的包,它相当简单:

    print PackageNameHere->meta->dump;
    

    对于更完整的数据:

    use Data::Dumper;
    print Dumper( PackageNameHere->meta ); 
    

    将帮助您入门。对于其他所有内容,->meta 上出现的方法记录在 Class::MOP::Class

    你可以对没有它的包做一些 AdHoc 假装驼鹿的好处:

    use Class::MOP::Class;
    my $meta = Class::MOP::Class->initialize( PackageNameHere );
    

    然后像使用 Moose 一样继续使用 Class::MOP 方法。

    对于初学者:

     $meta->get_method_map(); 
    

    使用 Moose; #,它的真棒

    【讨论】:

    • initialize 将返回元类,如果它被缓存,不需要手动检查它,例如在 Moose.pm 中查看所有糖的实现
    • 嗯,经过进一步调查,我似乎既对又错。 Class::MOP::class_of() 将处理实例以及类名,而初始化函数使用 (Class::MOP::get_metaclass_by_name()) 处理类名。
    • Kent - 这对我不起作用 - 也许 Moose 世界发生了一些变化。我有一个要点:gist.github.com/rjattrill/6119205
    【解决方案5】:

    一般来说,你不能用像 Perl 这样的动态语言来做到这一点。该包可能会定义一些您可以找到的方法,但它也可以即时组成在您使用它们之前没有定义的方法。此外,即使调用一个方法(有效)也可能不会定义它。这就是使动态语言变得更好的东西。 :)

    你想解决什么任务?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-16
      • 2013-03-19
      • 2014-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      相关资源
      最近更新 更多