Perl 5 - 在字符串中评估OO代码

时间:2016-11-14 14:08:13

标签: perl perl5

我的代码基本上是:

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

我想运行$object->$message();但我无法编译,所以我正在尝试

my $value = eval '$object->$message()';

但是这总是会返回undef。

我怀疑我的方法是错误的 - 如何在运行时运行这种字符串?

2 个答案:

答案 0 :(得分: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方法来获取coderef:

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

我不确定这通常是一件好事,因为它可能会变得非常混乱。我认为这种方法不太可能随意破坏而不是eval。

然而,您的原始方法 工作:

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

我认为你的sub可能是错误的 - 你试过检查$@这是eval的返回码吗?

答案 1 :(得分: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

  

方法名称为字符串

     

Perl允许您使用包含字符串的标量变量作为方法   名:

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

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

这与调用$file->save()完全相同。这对于编写动态代码非常有用。例如,它允许您将方法名称作为参数传递给另一个方法。

所以问题出在代码的其他地方。