sachin
sachin

Reputation: 359

Eval within if statement

How can I dynamically pass eq or ne inside perl if statement? I tried below but is not working:

my $this="this";
my $that="that";
my $cond='ne';
if($this eval($cond) $that)
{
  print "$cond\n";
}

Upvotes: 1

Views: 867

Answers (3)

Eric Strom
Eric Strom

Reputation: 40142

Whenever you are using eval for runtime code generation, it is best to keep in mind a few details. First, eval is dangerous, so you should eval the smallest, most generic code you can, and check for errors. Second, eval is slow, so you should store the result for later.

{my %cache;
sub compare {
    my ($x, $op, $y) = @_;
    $cache{$op} ||= eval "sub {\$_[0] $op \$_[1]}" || die "bad op: $op\n";
    $cache{$op}->($x, $y)
}}

my $this="this";
my $that="that";
my $cond='ne';

if (compare $this, $cond, $that) {
    print "$cond\n";
}

Here the compare function will build a new coderef (with eval) when it sees an operator that it has not had yet. The return value of the eval is checked, and an error is raised if anything when wrong.

This coderef (which expects its values as arguments) is stored in %cache. Then the cached coderef is run with the two values as arguments. This same coderef will be used over and over whenever the same operator is used.

Upvotes: 2

Eugene Yarmash
Eugene Yarmash

Reputation: 149776

You don't need eval for this. Just use a dispatch table:

sub test {
    my %op = (
        eq => sub { $_[0] eq $_[1] },
        ne => sub { $_[0] ne $_[1] },
    );
    return $op{ $_[2] }->($_[0], $_[1]);        
}

if (test($this, $that, $cond)){
    print "$cond\n";
}

Upvotes: 9

Dallaylaen
Dallaylaen

Reputation: 5308

if (($cond eq 'eq') xor ($this ne $that)) {
     print $cond;
};

But maybe a better and more general approach would be to use perl's functional capabilities and create a hash table of functions:

my %compare = (
     eq => sub {shift eq shift},
     ne => sub {shift ne shift},
     lt => sub {shift lt shift},
     like => sub {$_[0] =~ /$_[1]/},
     # ....
);

#...
if ($compare{$cond}->($this, $that)) {
     print $cond;
};

Upvotes: 7

Related Questions