문제

Perl에서 클래스의 모든 방법을 어떻게 반복합니까? Perl Introspection 또는 Reflection에 대한 온라인 참조가 좋은 것이 있습니까?

도움이 되었습니까?

해결책

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";
}

참조 클래스 :: mop :: 클래스 문서 내성을 수행하는 방법에 대한 자세한 내용.

또한 Moose 대신 Class :: Mop을 사용했습니다. 클래스 :: MOP (MOP = Meta-Object Protocol)는 무스가 구축하는 기반입니다. 유두 수업을 사용하지 않는 경우 무스를 사용하여 내성을 사용한다고해서 아무것도 얻지 못합니다.

당신이 원한다면, 당신은 할 수 있습니다 use Moose () 그리고 Moose::Meta::Class->initialize CMOP 대신.

다른 팁

이미 제공된 답변을 사용하여 클래스의 정의 된 메소드 목록을 쉽게 얻을 수 있습니다. 그러나 Perl은 동적 언어이므로 더 많은 방법이 나중에 정의 될 수 있음을 의미합니다. 특정 클래스가 처리 할 모든 방법의 목록을 얻는 방법은 실제로 없습니다. 이런 종류의 것들에 대해 훨씬 더 자세히 설명하려면 몇 장에 마스터 링 Perl.

사람들은 한계에 대해 말하지 않고 당신에게 (그리고 upvoting) 답변을주고 있습니다.

아담은 그의 언급을 언급합니다 클래스 :: 검사관, 그러나 그것은 역동적 인 언어가하지 않는 일을하려고 노력하고 있기 때문에 실제로 작동하지 않습니다 (그리고 그것은 정적입니다 :) 예를 들어, 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";

여기에 내가 좋아하는 메소드를 호출 할 수있는 또 다른 사례는 있지만 클래스 :: Inspector 만 반환합니다. 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";

흥미롭게도, 모든 사람들은 보편적 인 것을 무시하는 것 같습니다. 아마도 @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";

클래스 :: MOP 동일한 제한 사항이 있습니다.

모든 모듈이 AutoRoad를 사용하는 것은 아니지만 모호하거나 드문 기능도 아닙니다. 당신이 몇 가지 방법을 놓치지 않을 것이라면 클래스 :: 검사자 또는 클래스 :: mop은 괜찮을 것입니다. 모든 경우에 클래스 나 객체에서 호출 할 수있는 모든 방법의 목록을 제공하지는 않습니다.

클래스 나 객체가 있고 특정 방법을 호출 할 수 있는지 알고 싶다면 can ()을 사용하십시오. 평가 블록으로 싸서 CAN CAN CAL을 호출 할 수 있습니다.

if( eval { $object->can( 'method_name' ) } )
    {
    $object->( @args );
    }

일반적으로 기호 테이블을 검사해야합니다 (무스를 사용하지 않는 한). 예를 들어, 정의 된 메소드를 나열하려면 IO::File 패키지:

use IO::File;
no strict 'refs';
print join ', ', grep { defined &{"IO::File::$_"} } keys %{IO::File::};

해시 %{IO::File::} The의 기호 테이블입니다 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 남자 페이지.

당신이 의미하는지, 어떤 수업이든 또는 자신의 구현을 구현하고 있는지 여부에 따라 다릅니다. 후자는 사용합니다 엘크, 이러한 기능에 대해 매우 깨끗한 구문을 제공합니다. 요리 책에서 :

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

당신은 아마도 클래스 :: 검사관-> 메소드 ( 'your :: class')를 원할 것입니다.

그런가 말했다.

잊어 버릴 때 여기에 남겨 두겠습니다. 이것은 매우 강력합니다. 너무 나쁘다. 그것은 대부분의 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::;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top