help with eval

A

Alex Lee

Dear all:
I am getting this weird error message from eval even when @$ is not
set.
example:
eval '**1';

yeilds erorr outpu:
Number found where operator expected at (eval 1) line 1, near "**1"
(Missing operator before 1?)

I am using the active state 806 perl version: 5.8.0

Does anyone know how I can silence this error from eval? I read
something about patches for certain versions of perl, but do not have
any details.

thanks in advance.
al
 
T

Tad McClellan

Alex Lee said:
I am getting this weird error message


It is not weird at all, it is a normal syntax error message,
the same as if it was in a conventional program rather than
in an eval EXPR.

from eval even when @$ is not
^^
^^ huh?


Did you mean $@ instead?

For me it says:

syntax error at (eval 1) line 1, near "**1"

example:
eval '**1';


The exponentiation operator requires 2 operands, you have given
it only one.

yeilds erorr outpu:
Number found where operator expected at (eval 1) line 1, near "**1"
(Missing operator before 1?)
Does anyone know how I can silence this error from eval?


By giving it code that is free of syntax errors.

I read
something about patches for certain versions of perl, but do not have
any details.


That code will fail to run in all versions of Perl...




"eval EXPR" is dangerous and not for beginners.

What is it that you are actually trying to accomplish?

You can almost certainly get it done without resorting to the evil eval().



Have you seen the Posting Guidelines that are posted here frequently?
 
A

Alex Lee

Hi,
I don't think eval return errors unless you tell it to: its stored in
@$. I am using eval, and perhaps many other people are as well, to
trap syntax errors - thats the whole point. If you don't believe me
try:

eval ' 6+/ ';
or eval '6 /0';

The above example will return nothing , no error message, unless you
add:
warn $@ if $@;

Iam mot planning to use this on a server side script, thus i don't
think eval in this case is very 'evil' nor dangerous ;) In fact it is
very useful, as I said before, to trap fatal errors.

thanks.
al ;)
 
A

A. Sinan Unur

Hi,
I don't think eval return errors unless you tell it to: its stored in
@$.

ITYM @$. This is something Tad has already pointed out.

I will suggest reading perldoc -f eval as your understanding seems to be
muddled and you are throwing terms around without paying attention to their
meanings.
I am using eval, and perhaps many other people are as well, to
trap syntax errors - thats the whole point. If you don't believe me
try:

eval ' 6+/ ';
or eval '6 /0';

You should not use eval for syntax errors. That's what the Perl compiler is
for.
The above example will return nothing , no error message, unless you
add:
warn $@ if $@;

I am sure this is not a surprise to Tad.
In fact it is very useful, as I said before, to trap fatal errors.

Clearly, as we all know.

As for your original question:
I am getting this weird error message from eval even when @$ is not
set. example:
eval '**1';

yeilds erorr outpu:
Number found where operator expected at (eval 1) line 1, near "**1"
(Missing operator before 1?)

That is not a weird message. It is telling you exactly what is happening.
The exponentiation operator is a binary operator and hence requires two
operands.

If you had read the docs for eval, you would have noticed:

Beware that using "eval" neither silences perl from printing warnings
to STDERR, nor does it stuff the text of warning messages into $@.
 
A

A. Sinan Unur

ITYM @$. This is something Tad has already pointed out.

Sorry Tad! Tad pointed out that there is no such variable. The correct
variable is $@. I'll keep quiet for the rest of the day :)
 
B

Brian McCauley

Alex said:
I am getting this weird error message from eval even when @$ is not
set.
example:
eval '**1';

yeilds erorr outpu:
Number found where operator expected at (eval 1) line 1, near "**1"
(Missing operator before 1?)

The problem is that Perl compilation errors are not really errors in the
sense of being exceptions that that eval() can catch.

Compilation errors are more like mandatory warnings that also set a flag
that tiggers an "Execution ... aborted due to compilation errors" when
compilation completes. In eval() (at least in recent Perls) you
actually get the last compliation error rather than "Execution ...
aborted due to compilation errors" returned in $@.

To capture others you need something like:

#!/usr/bin/perl
use strict;
use warnings;

my ($stderr,$err);

{
open my $e_fh, '>', \$stderr or die $!;
# The orginal STDERR filehandle is special and
# cannot be redirected to a scalar but it can be
# temporarily replaced
local *STDERR = $e_fh;
eval '**1';
$err = $@;
}

print "Last error: $err\nOther errors: $stderr\n";
I am using the active state 806 perl version: 5.8.0

Note - I tested this in 5.8.4. I know this stuff has changed a lot in
recent versions of Perl. I suspect this may not work in 5.8.0.
 
A

A. Sinan Unur

This is getting kind of weird: all I ask was how I can silence eval.
Oh excuse my 'simple' language, to prevent eval from sending 'all'
warning messages to STDERR:

Ah-em, you would have gotten that answer if you had simply read:

perldoc -f eval
 
T

Tad McClellan

Alex Lee said:
I am using eval, and perhaps many other people are as well, to
trap syntax errors - thats the whole point.


There are 2 forms of eval(), a good one (eval BLOCK) and
a bad one (eval EXPR).

Many other people use "eval BLOCK" for exception handling.

People that use "eval EXPR" for exception handling are the exception.

Why can't you use the "eval BLOCK" form like you are supposed to?
 
J

Joe Smith

Alex said:
Does anyone know how I can silence this error from eval?

Simply redirect STDERR to a string in a BEGIN block.

linux% cat eval.pl
use strict; use warnings;
BEGIN { our $err = ''; close STDERR; open STDERR,'>',\$err; }
CHECK { our $err; print "Compile: $err" if $err; }
INIT { our $err = ''; close STDERR; open STDERR,'>',\$err; }
END { our $err; print "Runtime: $err" if $err; }

$_ = "abc" + 3;
$a = "xyz"; $b = 3; $_ = $a + $b;

# Uncomment the next line to watch a fatal compilation error get caught.
# $_ = "(e-mail address removed)";

linux% perl eval.pl
Compile: Argument "abc" isn't numeric in addition (+) at eval.pl line 7.
Runtime: Argument "xyz" isn't numeric in addition (+) at eval.pl line 8.

-Joe
 
J

Joe Smith

Brian said:
open my $e_fh, '>', \$stderr or die $!;
# The orginal STDERR filehandle is special and
# cannot be redirected to a scalar

The original STDERR filehandle is special.
In order to redirect STDERR to a scalar, it must be closed first,
as documented in 'perldoc -f open'.
-Joe
 
B

Brian McCauley

Joe said:
The original STDERR filehandle is special.
In order to redirect STDERR to a scalar, it must be closed first,
as documented in 'perldoc -f open'.

OK my statement was a simplification. Since as a general rule one does
not want STDERR to left without its specialness after a temporary
redirection it is simplest just to leave the original STDERR handle
untouched and temporarily associate the *STDERR GLOB with an ordinary
"capture to scalar" file handle.
 
A

Alex Lee

Brian, I think you made an excellent point there:
I made a over simplification by lumping errors and warnings together.
The simple solution to my original problem is to simply ignore the
warnings:

local $SIG{__WARN__}=sub{};
print eval "**1";
## found solution in "Perl Black Book"
Anyways thank you to all that post helful comments.
al ;)
 
B

Brian McCauley

A. Sinan Unur said:
Ah-em, you would have gotten that answer if you had simply read:

perldoc -f eval

Actually there are mistakes in that documentation...

If there is a syntax error or runtime error, or
a die statement is executed, an undefined value
is returned by eval, and $@ is set to the error
message. If there was no error, $@ is guaranteed to
be a null string. Beware that using eval neither
silences perl from printing warnings to STDERR,
nor does it stuff the text of warning messages into $@.
To do either of those, you have to use the $SIG{__WARN__}
facility, or turn off warnings inside the BLOCK
or EXPR using no warnings 'all'. See warn, the perlvar
manpage, the warnings manpage and the perllexwarn manpage.

Compilation errors, other than the last one, are treated as warnings and
will be captured as by the $SIG{__WARN__} handler. But if warnings are
disabled using 'no warnings' then all the compilation errors will not
set sent to the $SIG{__WARN__} or to STDERR be concetenated into $@.

Note also the warnings can be captured by capturing STDERR too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,891
Members
47,423
Latest member
henerygril

Latest Threads

Top