in reply to eval question

You could use CGI::Ex::Template which has exposed the expression parsing methods from the Template::Toolkit mini-language. This gives you all of the access to numeric extensions. You can also get support for variables (though you have to use the Template::Toolkit expression syntax for setting a variable (encasing the set expression in parens). And you can use the TT virtual methods (plus filters exposed by CGI::Ex::Template).

use strict; use CGI::Ex::Template; my $t = CGI::Ex::Template->new; ### hmm - semi documented $t->_vars({ PI => 3.14159, r => 1.5, }); foreach ("2 + 3", "1 + (2 + 4) / 3", "2 ** 3 ** 4", '12345.fmt("%.3e")', '0xFF', "PI", "PI * r ** 2", "1 + (", "foo", "(foo = 123456 + 1)", "foo", ) { my $expr = $_; print "-------------\n"; print "Expression: $expr\n"; my $optree = eval { $t->parse_expr(\$expr) }; #use CGI::Ex::Dump qw(debug); #debug $optree; my $result; if (my $err = $@) { print "Error: ".(ref $err ? $err->info : "$err")."\n"; } else { $result = $t->play_expr($optree); print "Result: $result\n"; } }
That chunk of code would print out the following:

------------- Expression: 2 + 3 Result: 5 ------------- Expression: 1 + (2 + 4) / 3 Result: 3 ------------- Expression: 2 ** 3 ** 4 Result: 2.41785163922926e+24 ------------- Expression: 12345.fmt("%.3e") Result: 1.234e+04 ------------- Expression: 0xFF Result: 255 ------------- Expression: PI Result: 3.14159 ------------- Expression: PI * r ** 2 Result: 7.0685775 ------------- Expression: 1 + ( Error: Missing close ) ------------- Expression: foo Result: ------------- Expression: (foo = 123456 + 1) Result: 123457 ------------- Expression: foo Result: 123457


I also noticed an interesting thing, the parsing of CGI:Ex::Template would turn 1 + * 3 into 1 + undef * 3 which would evaluate to 1 when you may have wanted it to report an error. I'll see if we can get a fix in for CGI::Ex::Template.

my @a=qw(random brilliant braindead); print $a[rand(@a)];