Eval в заявлении if - PullRequest
       0

Eval в заявлении if

1 голос
/ 20 декабря 2010

Как я могу динамически передать eq или ne внутри оператора perl if? Я попробовал ниже, но не работает:

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

Ответы [ 3 ]

9 голосов
/ 20 декабря 2010

Вам не нужно eval для этого. Просто используйте таблицу отправки :

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";
}
7 голосов
/ 20 декабря 2010
if (($cond eq 'eq') xor ($this ne $that)) {
     print $cond;
};

Но, возможно, лучшим и более общим подходом будет использование функциональных возможностей Perl и создание хэш-таблицы функций:

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;
};
2 голосов
/ 21 декабря 2010

Всякий раз, когда вы используете eval для генерации кода во время выполнения, лучше помнить несколько деталей. Во-первых, eval опасно, поэтому вы должны eval самый маленький, самый общий код, который вы можете, и проверять на наличие ошибок. Во-вторых, eval медленный, поэтому вы должны сохранить результат на потом.

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

Здесь функция compare создаст новую кодовую ссылку (с eval), когда увидит оператора, которого еще не было. Возвращаемое значение eval проверяется, и возникает ошибка, если что-то не так.

Этот код ссылки (который ожидает свои значения в качестве аргументов) хранится в %cache. Затем кешированный код запускается с двумя значениями в качестве аргументов. Один и тот же код будет использоваться снова и снова, когда используется один и тот же оператор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...