2016-11-14 2 views
-1

문자열에서 평가 OO 코드 기본적으로 :펄 5 - 나는 코드가

$object = Class->new(); 
$message = 'get_value': 

내가 $object->$message();를 실행하려는하지만 그 컴파일 얻을 수없는, 그래서

my $value = eval '$object->$message()'; 
을 시도하고있다

하지만 항상 undef가 반환됩니다.

내 접근 방식이 잘못되었다고 생각합니다. 런타임에 이러한 종류의 문자열을 어떻게 실행합니까?

+0

여기서 실제로 무엇을하려고합니까? 왜 동적 인 하위 이름을 지정하려고합니까? 좀 더 일반적인 방법은'$ object -> get_value ($ some_attribute_name)'또는 이와 비슷한 것이다. 이것은 [XY 문제] (http : //meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Sobrique

+3

그게 효과가있다. 실제 코드가 보이지 않습니다. – simbabque

+0

잘 찾아 냈습니다. 나는 문제가 없다는 것을 깨닫기 전에 문제를 찾아 나서고 갔다. – Sobrique

답변

3

나는 그것이 당신이 성취하고자하는 것에 달려 있다고 생각합니다. 이것은 다음과 같이 느껴질 것입니다. XY Problem

#!/usr/bin/env perl 
use strict; 
use warnings; 

package MyObject; 

sub new { 
    my ($class, %args) = @_; 
    my $self = {}; 
    $self->{args} = \%args; 
    bless $self, $class; 
    return $self; 
} 

sub get_value { 
    my ($self, $attribute) = @_; 
    return $self -> {args} -> {$attribute}; 
} 

package main; 

my $object = 'MyObject'->new(test => 'frobnicated', foo=>'bar'); 
print $object -> get_value('test'); 

그리고 메소드 자체에서 동적 비트를 처리하십시오. 당신이 코드 참조 얻기 위해 can 방법을 사용할 수있는 서브 루틴 '발견'할 경우

그러나 :

my $methodname = 'get_value'; 
if (my $coderef = $object -> can($methodname)) { 
    print $coderef -> ($object,'foo'); 
} 

잘 모르겠어요를 this'd 일반적으로 좋은 일이 될 일을 할 그래도 꽤 지저분해질 수 있습니다. 나는이 접근법이 eval보다 무작위로 깨지기 어렵다고 생각한다.

그러나 원래의 접근 방식 작동합니까 : 나는 당신의 서브 erroring되는 것 같아요

my $value = eval '$object->$methodname("foo")'; 
print $value,"\n"; 

을 - 당신이 eval의 리턴 코드가 [email protected]을 확인 시도?

+0

Ahah가 $ @를 확인하는 것이 중요합니다 :-(좋은 지적, 고마워요. –

+0

'my $ value = eval '$ object -> $ methodname ("foo")'; print $ value, "\ n"; 은 $ 자기 근처 나에게 '서브 GET을 구문 오류를 제공 { \t 내 $ 셀프 = 이동;? \t 내 %의 인수의 = (REF ($ _ [0]) EQ '해시') % {$ _ [0] } : @_; \t 반환하지 않는 한 ($ 인수 { '객체'} && $ 인수 { '메시지'}); \t = $ 인수 { '객체'} 오 내 $; \t 내 $ m = $ args { 'message'} \t my $ rc = eval '$ o -> $ m()'; \t die $ @ if $ @; return $ rc; }' –

+2

@NigelHorne : 주석에 코드를 넣지 마십시오. 이해하는 것이 거의 불가능합니다. 거기에 추가하려면 [질문 편집] (http://stackoverflow.com/posts/40590650/edit)을 클릭하십시오. –

1

초기 버전이 정상적으로 작동합니다.

#!/usr/bin/perl 

use strict; 
use warnings; 

package Class; 

sub new { 
    return bless { value => $_[1] }, $_[0]; 
} 

sub get_value { 
    return $_[0]->{value}; 
} 

package main; 

my $obj = Class->new('some value'); 
my $message = 'get_value'; 

print $obj->$message(); 

예상대로 작동하며 "일부 값"을 인쇄합니다. eval을 사용할 필요가 없습니다. perldoc perlobj에서

:

my $file = File->new($path, $data); 

my $method = 'save'; 
$file->$method(); 

이 정확히처럼 작동 끈

펄 당신이 방법 이름으로 문자열을 포함하는 스칼라 변수를 사용할 수 있습니다로

방법 이름 $file->save()으로 전화하십시오. 이것은 동적 코드 작성에 매우 유용 할 수 있습니다. 예를 들어, 다른 메소드에 매개 변수로 호출 할 메소드 이름을 전달할 수 있습니다.

그래서 문제는 코드의 다른 부분에 있습니다.