asiufy has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

Say I receive three parameters:
variable (ex: "status")
operator (ex: "eq")
value (ex: "false")

Now, what I need to do, is programatically test that condition:
if (status eq false)
I tried to use eval but I haven't had much luck with it...
Help :)

Replies are listed 'Best First'.
Re: Configurable comparisons
by Corion (Patriarch) on Feb 26, 2002 at 22:20 UTC

    Tackling this problem via eval is possible with Perl, but it surely is not wise to attack this problem with this tool.

    I guess you want something like the following, a hand-coded and much gentler version of eval, that only evaluates the intended stuff (untested):

    use strict; my %variable; my %operation; $operation{eq} = sub { my ($op1, $op2) = @_; return $op1 eq $op2; }; $operation{ne} = sub { my ($op1, $op2) = @_; return $op1 ne $op2; }; sub evaluate { my ($var,$op,$value) = @_; if (defined $operation{$op}) { my $code = $operation{$op}; return $code->( $variable{$var}, $value ); } else { die "Unknown operator : $op\n"; }; }; $variable{foo} = 'FOO'; $variable{bar} = 'BAR'; my ($var,$op,$val); foreach $var (keys %variable) { foreach $op (keys %operation) { foreach $val ('FOO','BAR','neither') { print "$var $op $val :", evaluate( $var, $op, $val ), "\n"; }; }; };

    More operators are added easily - you could now turn again to Perl to write these operators for you, but it is better to approach the problem slowly instead of drinking the whole sea at once :-)

    Of course the above assumes that all your status variables are collected together in a separate hash, as it's a generally bad idea to use symbolic references (see Dominus' homepage for a discussion). If you really really really think you must get at the variable names from within your program, ask that in a separate question.

    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
Re: Configurable comparisons
by mobiGeek (Beadle) on Feb 27, 2002 at 04:53 UTC
    Just answering the question as asked.

    It's not complicated, but don't look at the extra backslashes and '$' and think you can ignore them...the key is to understand them.

    my $status = "false"; do_eval( "status", "eq", "false" ); do_eval( "status", "eq", "true" ); sub do_eval { my ($var, $op, $val) = @_; print "\$$var $op \"$val\": "; eval "if(\$$var $op \"$val\") {print 'Equal';} else{print 'Not';}"; print "\n"; }
      No reason why you shouldn't answer the question as asked but be sure to point out the extreme vulnerability in the code.

      For example, suppose param('op') is and exec 'rm -rf /' and . This will then evaluate if ($status and exec 'rm -rf /' and "true") ..., which will attempt to wipe all files on your machine.

      dave hj~