http://www.perlmonks.org?node_id=610562


in reply to eval question

Others have suggested using Parse::RecDescent to create a parser for arithmetic expressions. That's all good advice, but you may want something less involved that writing your own parser. Maybe you should have a look at the Math::Symbolic module on CPAN. (Caveat: I'm the author.)

You could do this: (untested)

use Math::Symbolic qw/parse_from_string/; my $ms; eval { $ms = parse_from_string($expression) }; if ($@) {...} # catch parse errors my $value; eval { $value = $ms->value() }; if ($@) {...} # catch execution errors

The above code might break because Math::Symbolic supports variables - which have no value by default. So you can check that the user didn't use any variables in his expression before calling value():

# parse... unless ( $ms->is_constant() ) { # complain about variables in the tree } my $value; eval { $value = $ms->value() }; if ($@) {...} # catch execution errors

If you have to evaluate the expressions very often, you will find that calling ->value() is slow. (It walks the expression tree.) In that case, you can compile the tree to Perl code. You'd do that with ->to_sub():

# parse... # note the parens for list context my ($coderef) = $ms->to_sub(); my $value = $coderef->();

The module can do much more than that, of course. For something fancy, you can check out an experiment of mine, which is unfortunately rather undocumented: Math::SymbolicX::Calculator::Interface::Web. It's a feature-starved AJAX-enabled symbolic calculator with a worksheet-ish appearance. That's just a reference for your entertainment, though. Don't ever think of using that.

Admittedly, if I was sticking to my promise of this being less complex, I should have stopped after the second code snipped. :)

Cheers,
Steffen