in reply to Problem when comparing strings as opposed to numerical values

Firstly, there is no need in nested if's:

if ((eval "$hash{$filter[0]->[0]} $filter[0]->[1] $filter[0]->[2]") && + (eval $hash{$filter[1]->[0]} $filter[1]->[1] $filter[1]->[2]) && (eval "$hash{$filter[2]->[0]} $filter[2]->[1] $filter[2]->[2]")) { print OUTFILE $line, "\n"; }

Secondly, you have quotes (") missing in the second statement. This can be the source of the problem. You can try using other quoting operators.

Thirdly, it can be safer to write a specific function to perform any needed checks on your data:

sub check { my ($a, $check, $b) = @_; if ($check eq "==") { return $a == $b; } elsif ($check eq ">=") { return $a >= $b; } elsif ($check eq "<=") { return $a <= $b; } elsif ($check eq "eq") { return $a eq $b; } else { die "Unimplemented check $check" } } if (&check($hash{$filter[0]->[0]},$filter[0]->[1],$filter[0]->[2]) && +&check(...) && &check(...)) { print OUTFILE $line; }
Some syntax problems caused by special characters inside the strings will be also avoided by this method.

Sorry if my advice was wrong.

Replies are listed 'Best First'.
Re^2: Problem when comparing strings as opposed to numerical values
by dkhalfe (Acolyte) on Jul 19, 2012 at 21:00 UTC

    I tried it with the quotes but theres no output to the file.

    I also tried:

     (eval /$hash{/$filter[1]->[0]} $filter[1]->[1] $filter[1]->[2])

    that didnt work either. It only works when I manually type in 'eq' - Example:

     (eval $hash{$filter[1]->[0]} eq $filter[1]->[2])

    But my whole point is to use the reference to the array to pull the variable out which should be 'eq' in this case. I am stumped. Any ideas on what to do?

      What if you print what you are trying to eval? I mean, run perl -d <your script>.pl, set a breakpoint on the line where the string comparsion occurs (b <line number>), run program to that line (c) and enter: x "$hash{$filter[1]->[0]} $filter[1]->[1] $filter[1]->[2]". What will it print?

      Maybe using eval "q{$hash{$filter[1]->[0]}} $filter[1]->[1] q{$filter[1]->[2]}" can help, but it will break too if the strings contain some "{" or "}". What if you check for $@ special variable after running your evals?

      Are you sure it won't be easier and safer to write a special sub to perform the checking?

      Sorry if my advice was wrong.