如何遍历Perl中所有类的方法?是否有任何良好的在线引用Perl内省或反思?如何循环遍历Perl中所有类的方法?
回答
Todd Gardner给出的使用Moose的建议是一个不错的选择,但他选择的示例代码并不是很有帮助。
如果您使用类检查非穆斯,你会做这样的事情:
use Some::Class;
use Class::MOP;
my $meta = Class::MOP::Class->initialize('Some::Class');
for my $meth ($meta->get_all_methods) {
print $meth->fully_qualified_name, "\n";
}
关于如何做反省;详情请参阅Class::MOP::Class docs。
你还会注意到我使用了Class :: MOP而不是Moose。 Class :: MOP(MOP =元对象协议)是Moose构建的基础。如果你正在与非穆斯类一起工作,使用穆斯来反思并不会给你带来任何好处。
如果你愿意,你可以用use Moose()
和Moose::Meta::Class->initialize
代替CMOP。
取决于你的意思,任何课程,或者如果你正在实施你自己的。对于后者,我使用Moose,它为这些功能提供了非常干净的语法。从食谱:
my %attributes = %{ $self->meta->get_attribute_map };
for my $name (sort keys %attributes) {
my $attribute = $attributes{$name};
if ( $attribute->does('MyApp::Meta::Attribute::Trait::Labeled')
# ... keeps on
请注意,Moose不会找到任何属性,除非您首先使用Moose定义了自反类。 但是,方法内省以及其他大部分位都可以正常工作。 – 2009-06-20 19:47:40
在一般情况下,你必须检查符号表(除非你用麋)。例如,以列出IO::File
包中定义的方法:
use IO::File;
no strict 'refs';
print join ', ', grep { defined &{"IO::File::$_"} } keys %{IO::File::};
散列%{IO::File::}
是IO::File package
的符号表,以及grep
过滤掉非子程序条目(例如包变量)。
若要扩展此以包含继承方法,您必须递归搜索父类的符号表(@IO::File::ISA
)。
下面是一个完整的例子:
sub list_methods_for_class {
my $class = shift;
eval "require $class";
no strict 'refs';
my @methods = grep { defined &{$class . "::$_"} } keys %{$class . "::"};
push @methods, list_methods_for_class($_) foreach @{$class . "::ISA"};
return @methods;
}
有关包和符号表的详细信息,请参阅perlmod手册页。
并非每个方法都必须在符号表中定义,并且您缺少UNIVERSAL。 – 2009-06-21 13:17:44
我想知道,如果这个问题的任何解决方案,特别是这里的这个问题,每次调用代码时都会生成一个新的对象实例,并且在程序终止之前它会被回收或每个实例停留在内存中。因为在.NET和Java等其他语言中使用反射/自省,必须小心在哪里实例化类对象引用,否则每次调用都可以获得新实例。 – David 2012-12-24 07:55:37
您可能需要Class :: Inspector->方法('Your :: Class')。
Nuff说。
使用已经提供的答案,您可以轻松地获得已定义方法的列表。但是,Perl是一种动态语言,这意味着更多的方法可能会在以后定义。实际上没有办法获得任何特定类将处理的所有方法的列表。有关这类内容的更多细节,我在Mastering Perl中有几章。
人们给你(和upvoting)的答案,而不告诉你的限制。
Adam提到他的Class::Inspector,但它并没有真正的工作,因为它试图做一些动态语言不能做的事情(这是静态的:)例如,这是一个片段,其中Class :: Inspector不返回任何方法,但我仍然可以调用VERSION
方法(以及isa
和can
):
BEGIN {
package Foo;
our $VERSION = '1.23'
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # reports nothing
print Foo->VERSION, "\n";
这里就是我可以打电话给我喜欢的任何方法,另一种情况,但类::督察只返回AUTOLOAD
(现在仍然失踪VERSION
,isa
和can
):
BEGIN {
package Foo;
our $VERSION = '1.23';
my $object = bless {}, __PACKAGE__;
sub AUTOLOAD { $object }
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # reports only "AUTOLOAD"
print Foo->dog->cat->bird, "\n";
奇怪的是,每个人似乎都忽略了UNIVERSAL,可能是因为他们没有明确地处理它,因为它实际上只是在@ISA中。我可以添加一个debug
方法每一个类和类::督察还惦记着它,即使它是一个定义的方法:
BEGIN {
sub UNIVERSAL::debug { "Hello debugger!\n" }
package Foo;
}
use Class::Inspector;
my $methods = Class::Inspector->methods('Foo');
print "Methods are [@$methods]\n"; # still reports nothing
print Foo->debug, "\n";
Class::MOP具有相同的限制。
并非每个模块都将使用AUTOLOAD,但它也不是一个晦涩或罕见的功能。如果你不介意你会错过一些方法,那么Class :: Inspector或Class :: MOP可能没问题。这不会给你一个每种方法的清单,你可以在任何情况下调用一个类或一个对象。
如果您有一个类或一个对象,并且想知道是否可以调用某个特定方法,请使用can()。包装在一个eval块所以可以调用可以()上的东西,甚至没有对象仍找回假的,而不是死亡,在这些情况下:
if(eval { $object->can('method_name') })
{
$object->(@args);
}
我就离开这个这里当我忘记它。这是非常强大的;太糟糕了,大多数Perl程序员都从来没有体验过它。
package Foo;
use strict;
sub foo1 {};
sub foo2 {};
our $foo3 = sub{};
my $foo4 = "hello, world!";
package Bar;
use strict;
# woo, we're javascript!
(sub {
*Bar::foo1 = sub { print "hi!"; };
*Bar::foo2 = sub { print "hello!"; };
$Bar::foo1 = 200;
})->();
package main;
use strict;
use Data::Dumper;
$Data::Dumper::Deparse = 1;
print Dumper \%Data::Dumper::;
print Dumper \%Foo::;
print Dumper \%Bar::;
- 1. 循环遍历类的所有对象
- 2. 循环遍历所有值
- 3. 如何循环遍历所有路线?
- 4. 循环遍历UITableView中的所有UITextFields
- 5. 没有循环遍历所有文件
- 6. 循环遍历所有的记录和
- 7. 循环遍历所有组合
- 8. Sqlite循环遍历所有表
- 9. 循环遍历所有工作表VBA
- 10. 递归循环遍历类
- 11. Python for循环没有循环遍历所有项目
- 12. Powerpoint VBA循环没有循环遍历所有幻灯片
- 13. 我如何循环遍历OracleDataReader的所有列
- 14. 的Perl:如何循环遍历一个哈希
- 15. JQuery。每个类都不循环遍历所有元素
- 16. 如何正确循环遍历所有XML节点?
- 17. 循环遍历R中的文件夹中的所有文件
- 18. Python的 - 遍历所有类
- 19. 循环遍历LinkedList
- 20. 循环遍历ColdFusion中多个目录中的所有图像
- 21. 在C++中循环遍历Abstract类的所有子类是否可能?
- 22. 在ruby中循环遍历
- 23. 如何在PHP中循环遍历数组的循环?
- 24. 如何循环遍历NSMutableArray的值
- 25. foreach循环不遍历列表中的所有项目 - C#
- 26. 循环遍历表中的所有复选框
- 27. 循环遍历UICollectionview中的所有单元格
- 28. 循环遍历ResourceManager中的所有资源 - C#
- 29. 循环遍历工作簿中的所有工作表
- 30. 循环遍历.resx文件中的所有资源
对于第一个问题,请参阅:http://stackoverflow.com/questions/910430/how-do-i-list-available-methods-on-a-given-object-or-package-in -perl – molf 2009-06-20 14:47:38