Math-Expression
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
Expression.pm view on Meta::CPAN
if($fname eq 'push' or $fname eq 'unshift') {
# Evaluate right->right and push/unshift that
my $vn = shift @arglist; # var name
my @vv = $self->{VarGetFun}($self, $vn);# var value
my @vp = $self->EvalTree($tree->{right}->{right}, 0); # var to push/unshift
$fname eq 'push' ? push(@vv, @vp) : unshift(@vv, @vp);
$self->{VarSetFun}($self, $vn, @vv);
return scalar @vv;
}
return length($last) if($fname eq 'strlen');
return scalar @arglist if($fname eq 'count');
# aindex(array, val) returns index (from 0) of val in array, -1 on error
if($fname eq 'aindex') {
my $val = $arglist[$#arglist];
for( my $inx = 0; $inx <= $#arglist - 1; $inx++) {
return $inx if($val eq $arglist[$inx]);
}
return -1;
}
$self->PrintError("Unknown Function '$fname'");
return '';
}
# Create a new parse/evalutation object.
# Initialise default options.
sub new {
my $class = shift;
# What we store about this evaluation environment, default values:
my %ExprVars = (
PrintErrFunc => '', # Printf errors
VarHash => {( # Variable hash
EmptyArray => [()],
EmptyList => [()],
)},
VarGetFun => \&VarGetFun, # Get a variable - function
VarIsDefFun => \&VarIsDefFun, # Is a variable defined - function
VarSetFun => \&VarSetFun, # Set an array variable - function
VarSetScalar => \&VarSetScalar, # Set a scalar variable - function
FuncEval => \&FuncValue, # Evaluate - function
AutoInit => 0, # If true auto initialise variables
ExtraFuncEval => undef, # User supplied extra function evaluator function
RoundNegatives => 0, # Round behaves differently with -ve numbers
PermitLoops => 0, # Are loops allowed
MaxLoopCount => 50, # Max # all loops
ArrayMaxIndex => 100, # Max index of an array
StringMaxLength => 1000, # Max string length
EnablePrintf => 0, # Enable printf function
Functions => {%InFuns}, # Known functions, initialise to builtins
);
my $self = bless \%ExprVars => $class;
$self->SetOpt(@_); # Process new options
return $self;
}
# Set an option in the %template.
sub SetOpt {
my $self = shift @_;
while($#_ > 0) {
$self->PrintError("Unknown option '$_[0]'") unless(exists($self->{$_[0]}));
$self->PrintError("No value to option '$_[0]'") unless(defined($_[1]));
$self->{$_[0]} = $_[1];
shift;shift;
}
}
1;
__END__
=head1 NAME
Math::Expression - Safely evaluate arithmetic/string expressions
=head1 DESCRIPTION
Evaluating an expression from an untrusted source can result in security or denial of service attacks.
Sometimes this needs to be done to do what the user wants.
This module solves the problem of evaluating expressions read from sources such as config/...
files and user web forms without the use of C<eval>.
String and arithmetic operators are supported (as in C/Perl),
as are: variables, loops, conditions, arrays and be functions (inbuilt & user defined).
The program may set initial values for variables and obtain their values once the expression
has been evaluated.
The name-space is managed (for security), user provided functions may be specified to set/get
variable values.
Error messages may be via a user provided function.
This is not designed for high computation use.
=head1 EXAMPLE
Shipping cost depends on item price by some arbitrary formula. The VAT amount can also
vary depending on political edict. Rather than nail these formula into the application code the
formula are obtained at run time from some configuration source. These formula are
entered by a non technical manager and are thus not to be trusted.
use Math::Expression;
my $ArithEnv = new Math::Expression;
# Obtain from a configuration source:
my $ShippingFormula = 'Price >= 100 ? Price * 0.1 : (Price >= 50 ? Price * 0.15 : Price * 0.2)';
my $VatFormula = 'VatTax := Price * 0.2';
# Price of what you are selling, set the price variable:
my $price = 100;
$ArithEnv->VarSetScalar('Price', $price);
view all matches for this distributionview release on metacpan - search on metacpan
( run in 0.525 second using v1.00-cache-2.02-grep-82fe00e-cpan-3b7f77b76a6c )