如何遍歷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. 循環遍歷Bash中的所有列
- 5. 循環遍歷UITableView中的所有UITextFields
- 6. 的Xml Python的循環getIterator()方法不遍歷所有樹
- 7. Java:循環遍歷類路徑中的所有類
- 8. 沒有循環遍歷所有文件
- 9. 循環遍歷所有的記錄和
- 10. 循環遍歷所有工作表VBA
- 11. 循環遍歷所有組合
- 12. 循環遍歷所有main()參數
- 13. 使用jQuery循環遍歷所有LI's
- 14. 循環遍歷所有Unicode字符
- 15. Sqlite循環遍歷所有表
- 16. for循環不遍歷所有增量
- 17. For循環未遍歷所有數據
- 18. 如何循環遍歷複合CCArray中的所有對象
- 19. 如何循環遍歷表單中的所有元素jQuery
- 20. 如何循環遍歷QVBoxLayout中的所有小部件
- 21. 如何使用Applescript循環遍歷Excel中的所有行?
- 22. 遞歸循環遍歷類
- 23. Powerpoint VBA循環沒有循環遍歷所有幻燈片
- 24. Python for循環沒有循環遍歷所有項目
- 25. 如何在C#中循環遍歷所有ComboBoxes控件?
- 26. 如何循環遍歷R中的列
- 27. linux內核,如何循環遍歷所有的cpus?
- 28. 我如何循環遍歷OracleDataReader的所有列
- 29. 如何循環遍歷類似於for循環
- 30. 的Perl:如何循環遍歷一個哈希
對於第一個問題,請參閱: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