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.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
user589672
  • 61
  • 1
  • 2
  • 6
    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. – jiggy Jan 25 '11 at 21:42
  • 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. – user589672 Feb 01 '11 at 15:35

3 Answers3

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)

mob
  • 117,087
  • 18
  • 149
  • 283
  • 1
    blah blah blah use hashes instead they are blah blah and safer – P Shved Jan 25 '11 at 21:16
  • 4
    blah blah blah don't ever use string form of eval - see Perl Best practices Ch 8.7 and http://search.cpan.org/perldoc?Perl::Critic::Policy::BuiltinFunctions::ProhibitStringyEval – DVK Jan 25 '11 at 21:34
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().

runrig
  • 6,486
  • 2
  • 27
  • 44
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.

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
  • 1
    @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. – Eugene Yarmash Jan 25 '11 at 22:03
  • 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`" – DVK Jan 26 '11 at 00:33