Nigel Horne Nigel Horne - 22 days ago 5
Perl Question

Perl 5 - evaluating OO code in a string

I have code which is basically:

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


I want to run
$object->$message();
But I can't get that to compile, so I'm trying

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


But that always returns undef.

I suspect my approach is wrong - how do I run this sort of string at runtime?

Answer

I think it all depends on what you're trying to accomplish. This feels like an XY Problem

A more conventional approach would be to e.g.

#!/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'); 

And handle the dynamic bit in the method itself, for example.

However, if you do want to 'find' a subroutine you can use the can method to get the coderef:

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

I'm not sure this'd be generally a good thing to be doing though, as it could get quite messy. I think this approach is less likely to randomly break than eval though.

However your original approach does work:

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

I think it might be that your sub is erroring - have you tried checking $@ which is the return code from eval?