Home > database >  Perl: What is the preferred way of evaluating expressions besides eval?
Perl: What is the preferred way of evaluating expressions besides eval?

Time:12-01

I am attempting to use arithmetic to evaluate the a function, which is written as a string:

#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';
use feature 'say';
use autodie ':default';

my $str = '0.203580063041053 * $x   -0.0273785448865449';
my $x = 3;
my $ans = eval $str;
say $ans;

the above code works, and gives the correct answer.

However, perlcritic says that the above code is best avoided: Expression form of "eval" at line 10, column 11. See page 161 of PBP. (Severity: 5)

I have read that section of Perl's best practices, but it is very long, and I don't see how it applies to very simple situations like what I'm doing.

What is a good way of evaluating functions then?

CodePudding user response:

User @ikegami referred to another package in Algorithm::CurveFit, presumably Math::Symbolic.

The absolute simplest way that I can think of to write this is

#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';
use feature 'say';
use autodie ':default';
use Math::Symbolic ':all';

# https://metacpan.org/pod/Math::Symbolic
my $str = '0.203580063041053 * x   -0.0273785448865449';
my $x = 3;
my $tree = Math::Symbolic->parse_from_string($str);
my ($sub) = Math::Symbolic::Compiler->compile_to_sub($tree);
my $ans = $sub->($x);
say $ans;

this code is OK according to perlcritic, and does not use the eval loop.

I don't know why my ($sub) works, and my $sub doesn't work, I'd be grateful for an explanation.

CodePudding user response:

$str = '0.203580063041053 * $x -0.0273785448865449' is in essence a function so I would use 'sub' to create the function like so:

#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';
use feature 'say';
use autodie ':default';

sub str{
       my $x = shift;
       0.203580063041053 * $x   -0.0273785448865449;
}
my $x = 3;
my $ans = eval { str($x) } ;
say $ans;

  • Related