[win32] Trivial bugfix#2 from local repository
Gurusamy Sarathy [Sat, 6 Dec 1997 05:25:07 +0000 (00:25 -0500)]
Message-Id: <199712061025.FAA14396@aatma.engin.umich.edu>
Subject: Re: eval of sub gives spurious "uninitialised" warning

p4raw-id: //depot/win32/perl@382

op.c
pod/perldelta.pod
pod/perlfunc.pod
t/op/eval.t

diff --git a/op.c b/op.c
index d508bfb..ff17789 100644 (file)
--- 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);
index 7400940..5c99211 100644 (file)
@@ -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<eval EXPR> 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
index 887f827..49d455b 100644 (file)
@@ -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</wantarray> 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<perlvar>.
+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</warn> and L<perlvar>.
 
 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
index 6d0a67b..02b1045 100755 (executable)
@@ -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";
+}