2011-06-09 73 views

回答

5

不可能。沒有辦法區分子是否是方法。如果你可以用列表來代替,你可以使用

grep exists(&{ 'Foo::Bar::'.$_ }), keys %Foo::Bar:: 

當然,這不會掃描繼承樹。如果你想這樣做,你可以得到的軟件包列表進行掃描使用

mro::get_linear_isa('Foo::Bar') 
+6

也AUTOLOAD可以動態創建方法,可能會或可能不會在符號表中顯示 – mirod 2011-06-09 09:10:45

+0

謝謝!我可以逃避這一點。我可能會保持它的硬編碼。我認爲它不會經常改變,如果有的話。那麼爲什麼要花費CPU週期。 – 2011-06-09 13:41:57

+2

@mirod,我沒有提到AUTOLOAD,因爲不可能知道'AUTOLOAD'會處理什麼名字,不管它是否會在以後爲它們創建一個子類。 – ikegami 2011-06-09 17:18:21

4

嗯,嚴格來說這是不可能的潛艇和方法來區分,如池上提及。

但是如果你的創意,你可以隨時使用PadWalker'speek_subclosed_over到有點八九不離十在絕大多數情況下,從方法區分子, 雖然當然假陽性和假陰性是可能的:

use strict; 
use warnings; 

use PadWalker; 

my $self; 

sub test_sub 
{ 
    my $x = shift; 
    print $self; 
} 

sub test_method 
{ 
    my $self = shift; 
} 

sub is_method 
{ 
    my $coderef = shift; 
    my $all = PadWalker::peek_sub($coderef); 
    my $closed = PadWalker::closed_over($coderef); 
    for my $k (qw($self $me $class)) { 
     return 1 if $all->{$k} && !$closed->{$k}; 
    } 
    return 0; 
} 

print "test_sub: ", is_method(\&test_sub) ? 
    "is a method\n" : "is a sub\n"; 
print "test_method: ", is_method(\&test_method) ? 
    "is a method\n" : "is a sub\n"; 

獲取coderefs留給讀者一個練習。

4

ikegami的答案的替代方法是使用Package::Stash模塊。它的list_all_symbols方法將給你在給定包中的所有子名稱。這裏有一個例子:

perl -MPackage::Stash -E "say for Package::Stash->new('Package::Stash')->list_all_symbols('CODE')" 
+0

我不知道-E。涼。 – 2011-06-09 13:52:55

1

如果你已經使用了Moose,你可以使用Class :: MOP來做到這一點。我認爲Class :: MOP是最乾淨的方法,你也可以從繼承中獲取所有的方法/函數。但是像其他人說的那樣,你不能區分方法和功能。

use Class::MOP; 
use Test::More; 

my $class = Class::MOP::Class->initialize('Test::More'); 
my @methods  = $class->get_method_list(); # Only Methods in this Class 
my @all_methods = $class->get_all_methods(); # Include all inherited methods 

printf "%d functions in Test::More\n", scalar @methods; 
printf "%d functions including inheritance\n", scalar @all_methods; 

print "methods:  @methods\n\n"; 
print "all methods: ", join(' ', map({ $_->fully_qualified_name } @all_methods)), "\n"; 

這些版畫somethink這樣的:

39 functions in Test::More 
49 functions including inheritance 
methods:  subtest _whoa cmp_ok isa_ok use_ok isnt _format_stack like _eq_array plan _eval fail _carp done_testing _type diag _is_module_name import_extra eq_array require_ok BAIL_OUT _dne is ok _eq_hash explain todo todo_skip unlike new_ok eq_set pass can_ok eq_hash is_deeply note _equal_nonrefs _deep_check skip 
all methods: Exporter::export_fail Test::More::_whoa Test::More::subtest Exporter::export_tags Test::More::cmp_ok Test::More::use_ok Test::More::isa_ok Test::More::_format_stack Test::More::isnt Test::More::like Test::More::_eq_array Test::More::plan Exporter::export Test::More::_eval Test::More::_carp Test::More::fail Test::More::done_testing Test::More::_type Test::More::diag Test::Builder::Module::_strip_imports Test::More::_is_module_name Test::More::import_extra Exporter::as_heavy Test::More::eq_array Test::More::require_ok Exporter::export_to_level Test::More::BAIL_OUT Test::More::_dne Test::More::is Test::More::ok Exporter::export_ok_tags Test::More::explain Test::More::_eq_hash Test::More::todo_skip Test::More::todo Test::More::new_ok Test::More::unlike Test::More::pass Test::More::eq_set Test::More::can_ok Test::More::eq_hash Test::More::is_deeply Test::More::note Test::Builder::Module::import Test::More::_equal_nonrefs Test::More::skip Test::More::_deep_check Exporter::require_version Test::Builder::Module::builder 
相關問題