#!./perl
-print "1..27\n";
+print "1..40\n";
eval 'print "ok 1\n";';
my $x = 25;
eval <<'EOT'; die if $@;
- sub do_eval {
+ print "# $x\n"; # clone into eval's pad
+ sub do_eval1 {
eval $_[0]; die if $@;
}
EOT
-do_eval('print "ok $x\n"');
+do_eval1('print "ok $x\n"');
$x++;
-do_eval('eval q[print "ok $x\n"]');
+do_eval1('eval q[print "ok $x\n"]');
$x++;
-do_eval('sub { eval q[print "ok $x\n"] }->()');
+do_eval1('sub { eval q[print "ok $x\n"] }->()');
+$x++;
+
+# calls from within eval'' should clone outer lexicals
+
+eval <<'EOT'; die if $@;
+ sub do_eval2 {
+ eval $_[0]; die if $@;
+ }
+do_eval2('print "ok $x\n"');
+$x++;
+do_eval2('eval q[print "ok $x\n"]');
+$x++;
+do_eval2('sub { eval q[print "ok $x\n"] }->()');
+$x++;
+EOT
+
+# calls outside eval'' should NOT clone lexicals from called context
+
+$main::x = 'ok';
+eval <<'EOT'; die if $@;
+ # $x unbound here
+ sub do_eval3 {
+ eval $_[0]; die if $@;
+ }
+EOT
+do_eval3('print "$x ' . $x . '\n"');
+$x++;
+do_eval3('eval q[print "$x ' . $x . '\n"]');
+$x++;
+do_eval3('sub { eval q[print "$x ' . $x . '\n"] }->()');
$x++;
# can recursive subroutine-call inside eval'' see its own lexicals?
local $SIG{__WARN__} = sub { die "not ok $x\n" if $_[0] =~ /^Deep recurs/ };
recurse($x-5);
}
+$x++;
+
+# do closures created within eval bind correctly?
+eval <<'EOT';
+ sub create_closure {
+ my $self = shift;
+ return sub {
+ print $self;
+ };
+ }
+EOT
+create_closure("ok $x\n")->();
+$x++;
+
+# does lexical search terminate correctly at subroutine boundary?
+$main::r = "ok $x\n";
+sub terminal { eval 'print $r' }
+{
+ my $r = "not ok $x\n";
+ eval 'terminal($r)';
+}
+$x++;
+
+# Have we cured panic which occurred with require/eval in die handler ?
+$SIG{__DIE__} = sub { eval {1}; die shift };
+eval { die "ok ".$x++,"\n" };
+print $@;
+
+# does scalar eval"" pop stack correctly?
+{
+ my $c = eval "(1,2)x10";
+ print $c eq '2222222222' ? "ok $x\n" : "# $c\nnot ok $x\n";
+ $x++;
+}
+
+# return from eval {} should clear $@ correctly
+{
+ my $status = eval {
+ eval { die };
+ print "# eval { return } test\n";
+ return; # removing this changes behavior
+ };
+ print "not " if $@;
+ print "ok $x\n";
+ $x++;
+}
+
+# ditto for eval ""
+{
+ my $status = eval q{
+ eval q{ die };
+ print "# eval q{ return } test\n";
+ return; # removing this changes behavior
+ };
+ print "not " if $@;
+ print "ok $x\n";
+ $x++;
+}