http://qs321.pair.com?node_id=1060579

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

I have a string named $rule_text an it contains:
($field[6] eq 'PM' && $field[8] eq 'CAVENDI')
How can I use that in an if statement? Obviously if I just do this: if $rule_text {...} it'll evaluate as true as long as it's not an empty string but that's not correct. I want to know if that string evaluates as true or false and set a flag variable as appropriate. I was hoping that this would work:
$ignore_flag = eval if $rule_text;
but no luck.

Replies are listed 'Best First'.
Re: testing an if statement in a string
by Limbic~Region (Chancellor) on Oct 31, 2013 at 14:20 UTC
    brcjacks,

    eval

    It is generally considered very dangerous to evaluate code that your program didn't generate itself. This is because of the potential to introduce code you didn't expect. If you are obtaining this scalar externally, I would highly recommend you read about tainting as well.

    Cheers - L~R

      I have control over the input. It's coming from a database that I, or other developer, populate. Basically, I'm building a series of these tests based on db records. Thanks for the tip.
Re: testing an if statement in a string
by LanX (Saint) on Oct 31, 2013 at 14:18 UTC
    if( eval($rule_text) ) {···}

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      thanks for the quick reply. I had a feeling it was something simple.
Re: testing an if statement in a string
by pajout (Curate) on Oct 31, 2013 at 14:24 UTC
    my @field = (0,0,0,0,0,0,'PM',0,'CAVENDI'); my $cond = q(($field[6] eq 'PM' && $field[8] eq 'CAVENDI')); my $ret; eval "\$ret = $cond"; warn $@ if $@; print $ret;
      > eval "\$ret = $cond";

      a bit over complicated , eval returns (like sub or do) the result of the last expression.

      DB<105> $cond = q($field[6] eq 'PM' && $field[8] eq 'CAVENDI'); => "\$field[6] eq 'PM' && \$field[8] eq 'CAVENDI'" DB<106> @field = () DB<107> $ret =eval $cond => "" DB<108> @field = (0,0,0,0,0,0,'PM',0,'CAVENDI') => (0, 0, 0, 0, 0, 0, "PM", 0, "CAVENDI") DB<109> $ret =eval $cond => 1

      but checking $@ is always a good idea! =)

      update

      or an additional eval BLOCK to catch all error

      ~$ perl $cond="bla eqx 2"; eval { $ret =eval $cond } or warn "Problem with $cond"; __END__ Problem with bla eqx 2 at - line 2.

      Cheers Rolf

      ( addicted to the Perl Programming Language)

      Interesting. Why the double parenthesis in line 2?
        Why the double parenthesis in line 2?

        The outermost pair of parens are simply the paired delimiters of the  q// operator; a wide range of delimiters, paired or not, can be used by the various string and regex operators. The inner parens are copied from the string as it was given in the OP.

        >perl -wMstrict -le "my $s = q(foo); print qq{'$s'}; ;; $s = q((bar)); print qq/'$s'/; " 'foo' '(bar)'

        See Quote and Quote-like Operators (and also Regexp Quote-Like Operators) in perlop.

Re: testing an if statement in a string
by Laurent_R (Canon) on Oct 31, 2013 at 15:21 UTC

    Do you really need to store your conditions in a string? If the context permits it, you may as well store it in a code reference, as shown in the following session under the debugger:

    DB<1> @field = qw/0 0 0 0 0 0 PM 0 CAVENDI/; DB<2> $code_ref = sub {$field[shift] eq 'PM' && $field[shift] eq ' +CAVENDI'}; DB<3> $ignore_flag = $code_ref->(6, 8) DB<4> p $ignore_flag 1 DB<5> $ignore_flag = $code_ref->(3, 8) DB<6> p $ignore_flag DB<7> print "true" if $code_ref->(6, 8) true DB<8> print "true" if $code_ref->(3, 8) DB<9>

    Here, I have added a feature (dynamic passing of the array subscripts as parameters to the coderef), but the subscripts might as well be hard coded as in your original example.