From: Gurusamy Sarathy Date: Sat, 6 Dec 1997 05:25:07 +0000 (-0500) Subject: [win32] Trivial bugfix#2 from local repository X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c7cc6f1c203c4e65db1c0f5cee7626570fbf65fd;p=p5sagit%2Fp5-mst-13.2.git [win32] Trivial bugfix#2 from local repository Message-Id: <199712061025.FAA14396@aatma.engin.umich.edu> Subject: Re: eval of sub gives spurious "uninitialised" warning p4raw-id: //depot/win32/perl@382 --- diff --git a/op.c b/op.c index d508bfb..ff17789 100644 --- a/op.c +++ b/op.c @@ -3873,6 +3873,8 @@ ck_eval(OP *o) enter->op_other = o; return o; } + else + scalar(kid); } else { op_free(o); diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 7400940..5c99211 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -169,6 +169,23 @@ also return the undefined value if a subroutine's return value will not be used at all, which allows subroutines to avoid a time-consuming calculation of a return value if it isn't going to be used. +=head2 C determines value of EXPR in scalar context + +Perl (version 5) used to determine the value of EXPR inconsistently, +sometimes incorrectly using the surrounding context for the determination. +Now, the value of EXPR (before being parsed by eval) is always determined in +a scalar context. Once parsed, it is executed as before, by providing +the context that the scope surrounding the eval provided. This change +makes the behavior Perl4 compatible, besides fixing bugs resulting from +the inconsistent behavior. This program: + + @a = qw(time now is time); + print eval @a; + print '|', scalar eval @a; + +used to print something like "timenowis881399109|4", but now (and in perl4) +prints "4|4". + =head2 Changes to tainting checks A bug in previous versions may have failed to detect some insecure diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod index 887f827..49d455b 100644 --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -972,22 +972,38 @@ input operators return undef when they run out of data. =item eval BLOCK -EXPR is parsed and executed as if it were a little Perl program. It -is executed in the context of the current Perl program, so that any +In the first form, the return value of EXPR is parsed and executed as if it +were a little Perl program. The value of the expression (which is itself +determined within a scalar context) is first parsed, and if there are no +errors, executed in the context of the current Perl program, so that any variable settings or subroutine and format definitions remain afterwards. -The value returned is the value of the last expression evaluated, or a -return statement may be used, just as with subroutines. The last -expression is evaluated in scalar or array context, depending on the -context of the eval. +Note that the value is parsed every time the eval executes. If EXPR is +omitted, evaluates C<$_>. This form is typically used to delay parsing +and subsequent execution of the text of EXPR until run time. + +In the second form, the code within the BLOCK is parsed only once--at the +same time the code surrounding the eval itself was parsed--and executed +within the context of the current Perl program. This form is typically +used to trap exceptions more efficiently than the first (see below), while +also providing the benefit of checking the code within BLOCK at compile +time. + +The final semicolon, if any, may be omitted from the value of EXPR or within +the BLOCK. + +In both forms, the value returned is the value of the last expression +evaluated inside the mini-program, or a return statement may be used, just +as with subroutines. The expression providing the return value is evaluated +in void, scalar or array context, depending on the context of the eval itself. +See L for more on how the evaluation context can be determined. If there is a syntax error or runtime error, or a die() statement is executed, an undefined value is returned by eval(), and C<$@> is set to the error message. If there was no error, C<$@> is guaranteed to be a null -string. If EXPR is omitted, evaluates C<$_>. The final semicolon, if -any, may be omitted from the expression. Beware that using eval() -neither silences perl from printing warnings to STDERR, nor does it -stuff the text of warning messages into C<$@>. To do either of those, -you have to use the C<$SIG{__WARN__}> facility. See warn() and L. +string. Beware that using eval() neither silences perl from printing +warnings to STDERR, nor does it stuff the text of warning messages into C<$@>. +To do either of those, you have to use the C<$SIG{__WARN__}> facility. See +L and L. Note that, because eval() traps otherwise-fatal errors, it is useful for determining whether a particular feature (such as socket() or symlink()) @@ -1025,8 +1041,8 @@ die() again, which has the effect of changing their error messages: # __DIE__ hooks may modify error messages { local $SIG{'__DIE__'} = sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x }; - eval { die "foo foofs here" }; - print $@ if $@; # prints "bar barfs here" + eval { die "foo lives here" }; + print $@ if $@; # prints "bar lives here" } With an eval(), you should be especially careful to remember what's diff --git a/t/op/eval.t b/t/op/eval.t index 6d0a67b..02b1045 100755 --- a/t/op/eval.t +++ b/t/op/eval.t @@ -2,7 +2,7 @@ # $RCSfile: eval.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:48 $ -print "1..16\n"; +print "1..22\n"; eval 'print "ok 1\n";'; @@ -54,4 +54,21 @@ eval { 1; } || print "ok 15\n$@"; - +# check whether eval EXPR determines value of EXPR correctly + +{ + my @a = qw(a b c d); + my @b = eval @a; + print "@b" eq '4' ? "ok 17\n" : "not ok 17\n"; + print $@ ? "not ok 18\n" : "ok 18\n"; + + my $a = q[defined(wantarray) ? (wantarray ? ($b='A') : ($b='S')) : ($b='V')]; + my $b; + @a = eval $a; + print "@a" eq 'A' ? "ok 19\n" : "# $b\nnot ok 19\n"; + print $b eq 'A' ? "ok 20\n" : "# $b\nnot ok 20\n"; + $_ = eval $a; + print $b eq 'S' ? "ok 21\n" : "# $b\nnot ok 21\n"; + eval $a; + print $b eq 'V' ? "ok 22\n" : "# $b\nnot ok 22\n"; +}