Warnings in Perl Eval
Asked Answered
G

3

6

I need to hide warnings within eval but the rest of the code should continue to throw warning messages. Here is what I have -

eval "\$value = $hash->{key}";

now value of $hash->{key} could be a function call, like:

$hash->{key} = "function(0.01*$another_var)";

The problem comes when $another_var is undef (or ""). The script just craps out with the following message -

Argument "" isn't numeric in multiplication (*) at (eval 1381) line 1.

Any suggestions how I can avoid this? One option i was thinking was to parse the value inside parenthesis and evaluate that first, but its quite complex with the data I am dealing with.

Guardian answered 25/1, 2011 at 20:51 Comment(2)
I think you seriously need to rethink your approach if you are doing a string eval. Perl supports first-class functions so you can almost certainly achieve what you want without eval or suppressing warnings. If you could give a clearer picture of the underlying problem, you would get a better answer.Clearance
Thanks. I hear you on the string eval part. So I have a data file of sorts, lets say it has 2 columns A and B. Now based on a config file I can come up with a third column C which is 0.01 * B (or $B). But I cant say if there will always be something in column B nor do I know if the user wants $B or $A until I hit the eval.Guardian
B
10

Wrap your code in a no warnings block.

...
{
    no warnings;
    eval "\$value = $hash->{key}";
}
...

You can also disable specific classes of warnings. See perllexwarn for the hierarchy of warning categories and perldiag for the category that any particular warning belongs to.

{
    no warnings qw(uninitialized numeric);
    eval "\$value = $hash->{key}";
}

(blah blah blah standard disclaimer that any one who would disable warnings is unfit to get within 25 feet of an adding machine blah blah)

Bootlace answered 25/1, 2011 at 21:11 Comment(2)
blah blah blah use hashes instead they are blah blah and saferTripura
blah blah blah don't ever use string form of eval - see Perl Best practices Ch 8.7 and search.cpan.org/…Rockery
L
3

Are you sure you wouldn't rather do something like:

my $href;
my $somevar = 8;
$href->{foo} = sub { $somevar * 4 };
my $var = $href->{foo}->();

If you're not sure whether $href->{foo} is a scalar, code ref, etc, you can check it with the ref() function, or better, with Scalar::Util::reftype().

Landers answered 25/1, 2011 at 22:35 Comment(0)
D
0

Change the hash key to be "function( 0.01 * ($another_var // 0) )"

$another_var // 0 is equivalent to defined($another_var) ? $another_var : 0.

Dissertation answered 25/1, 2011 at 21:42 Comment(2)
@Pavel: this operator appeared in Perl 5.10 (released December 18th, 2007). One can also backport it into 5.8.x with the dor-patch.Dissertation
most people who run Perl5.8 don't have an option to patch it. Or else they wouldn't be stuck on 5.8. So it's good form to inform people when you use features from 5.10+ (best of all, by doing appropriate "use"Rockery

© 2022 - 2024 — McMap. All rights reserved.