summaryrefslogtreecommitdiffstats
path: root/contrib/perl5/t/op/closure.t
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/perl5/t/op/closure.t')
-rwxr-xr-xcontrib/perl5/t/op/closure.t507
1 files changed, 0 insertions, 507 deletions
diff --git a/contrib/perl5/t/op/closure.t b/contrib/perl5/t/op/closure.t
deleted file mode 100755
index 5f3245f..0000000
--- a/contrib/perl5/t/op/closure.t
+++ /dev/null
@@ -1,507 +0,0 @@
-#!./perl
-# -*- Mode: Perl -*-
-# closure.t:
-# Original written by Ulrich Pfeifer on 2 Jan 1997.
-# Greatly extended by Tom Phoenix <rootbeer@teleport.com> on 28 Jan 1997.
-#
-
-BEGIN {
- chdir 't' if -d 't';
- @INC = '../lib';
-}
-
-use Config;
-
-print "1..171\n";
-
-my $test = 1;
-sub test (&) {
- print ((&{$_[0]})?"ok $test\n":"not ok $test\n");
- $test++;
-}
-
-my $i = 1;
-sub foo { $i = shift if @_; $i }
-
-# no closure
-test { foo == 1 };
-foo(2);
-test { foo == 2 };
-
-# closure: lexical outside sub
-my $foo = sub {$i = shift if @_; $i };
-my $bar = sub {$i = shift if @_; $i };
-test {&$foo() == 2 };
-&$foo(3);
-test {&$foo() == 3 };
-# did the lexical change?
-test { foo == 3 and $i == 3};
-# did the second closure notice?
-test {&$bar() == 3 };
-
-# closure: lexical inside sub
-sub bar {
- my $i = shift;
- sub { $i = shift if @_; $i }
-}
-
-$foo = bar(4);
-$bar = bar(5);
-test {&$foo() == 4 };
-&$foo(6);
-test {&$foo() == 6 };
-test {&$bar() == 5 };
-
-# nested closures
-sub bizz {
- my $i = 7;
- if (@_) {
- my $i = shift;
- sub {$i = shift if @_; $i };
- } else {
- my $i = $i;
- sub {$i = shift if @_; $i };
- }
-}
-$foo = bizz();
-$bar = bizz();
-test {&$foo() == 7 };
-&$foo(8);
-test {&$foo() == 8 };
-test {&$bar() == 7 };
-
-$foo = bizz(9);
-$bar = bizz(10);
-test {&$foo(11)-1 == &$bar()};
-
-my @foo;
-for (qw(0 1 2 3 4)) {
- my $i = $_;
- $foo[$_] = sub {$i = shift if @_; $i };
-}
-
-test {
- &{$foo[0]}() == 0 and
- &{$foo[1]}() == 1 and
- &{$foo[2]}() == 2 and
- &{$foo[3]}() == 3 and
- &{$foo[4]}() == 4
- };
-
-for (0 .. 4) {
- &{$foo[$_]}(4-$_);
-}
-
-test {
- &{$foo[0]}() == 4 and
- &{$foo[1]}() == 3 and
- &{$foo[2]}() == 2 and
- &{$foo[3]}() == 1 and
- &{$foo[4]}() == 0
- };
-
-sub barf {
- my @foo;
- for (qw(0 1 2 3 4)) {
- my $i = $_;
- $foo[$_] = sub {$i = shift if @_; $i };
- }
- @foo;
-}
-
-@foo = barf();
-test {
- &{$foo[0]}() == 0 and
- &{$foo[1]}() == 1 and
- &{$foo[2]}() == 2 and
- &{$foo[3]}() == 3 and
- &{$foo[4]}() == 4
- };
-
-for (0 .. 4) {
- &{$foo[$_]}(4-$_);
-}
-
-test {
- &{$foo[0]}() == 4 and
- &{$foo[1]}() == 3 and
- &{$foo[2]}() == 2 and
- &{$foo[3]}() == 1 and
- &{$foo[4]}() == 0
- };
-
-# test if closures get created in optimized for loops
-
-my %foo;
-for my $n ('A'..'E') {
- $foo{$n} = sub { $n eq $_[0] };
-}
-
-test {
- &{$foo{A}}('A') and
- &{$foo{B}}('B') and
- &{$foo{C}}('C') and
- &{$foo{D}}('D') and
- &{$foo{E}}('E')
-};
-
-for my $n (0..4) {
- $foo[$n] = sub { $n == $_[0] };
-}
-
-test {
- &{$foo[0]}(0) and
- &{$foo[1]}(1) and
- &{$foo[2]}(2) and
- &{$foo[3]}(3) and
- &{$foo[4]}(4)
-};
-
-for my $n (0..4) {
- $foo[$n] = sub {
- # no intervening reference to $n here
- sub { $n == $_[0] }
- };
-}
-
-test {
- $foo[0]->()->(0) and
- $foo[1]->()->(1) and
- $foo[2]->()->(2) and
- $foo[3]->()->(3) and
- $foo[4]->()->(4)
-};
-
-{
- my $w;
- $w = sub {
- my ($i) = @_;
- test { $i == 10 };
- sub { $w };
- };
- $w->(10);
-}
-
-# Additional tests by Tom Phoenix <rootbeer@teleport.com>.
-
-{
- use strict;
-
- use vars qw!$test!;
- my($debugging, %expected, $inner_type, $where_declared, $within);
- my($nc_attempt, $call_outer, $call_inner, $undef_outer);
- my($code, $inner_sub_test, $expected, $line, $errors, $output);
- my(@inners, $sub_test, $pid);
- $debugging = 1 if defined($ARGV[0]) and $ARGV[0] eq '-debug';
-
- # The expected values for these tests
- %expected = (
- 'global_scalar' => 1001,
- 'global_array' => 2101,
- 'global_hash' => 3004,
- 'fs_scalar' => 4001,
- 'fs_array' => 5101,
- 'fs_hash' => 6004,
- 'sub_scalar' => 7001,
- 'sub_array' => 8101,
- 'sub_hash' => 9004,
- 'foreach' => 10011,
- );
-
- # Our innermost sub is either named or anonymous
- for $inner_type (qw!named anon!) {
- # And it may be declared at filescope, within a named
- # sub, or within an anon sub
- for $where_declared (qw!filescope in_named in_anon!) {
- # And that, in turn, may be within a foreach loop,
- # a naked block, or another named sub
- for $within (qw!foreach naked other_sub!) {
-
- # Here are a number of variables which show what's
- # going on, in a way.
- $nc_attempt = 0+ # Named closure attempted
- ( ($inner_type eq 'named') ||
- ($within eq 'other_sub') ) ;
- $call_inner = 0+ # Need to call &inner
- ( ($inner_type eq 'anon') &&
- ($within eq 'other_sub') ) ;
- $call_outer = 0+ # Need to call &outer or &$outer
- ( ($inner_type eq 'anon') &&
- ($within ne 'other_sub') ) ;
- $undef_outer = 0+ # $outer is created but unused
- ( ($where_declared eq 'in_anon') &&
- (not $call_outer) ) ;
-
- $code = "# This is a test script built by t/op/closure.t\n\n";
-
- $code .= <<"DEBUG_INFO" if $debugging;
-# inner_type: $inner_type
-# where_declared: $where_declared
-# within: $within
-# nc_attempt: $nc_attempt
-# call_inner: $call_inner
-# call_outer: $call_outer
-# undef_outer: $undef_outer
-DEBUG_INFO
-
- $code .= <<"END_MARK_ONE";
-
-BEGIN { \$SIG{__WARN__} = sub {
- my \$msg = \$_[0];
-END_MARK_ONE
-
- $code .= <<"END_MARK_TWO" if $nc_attempt;
- return if index(\$msg, 'will not stay shared') != -1;
- return if index(\$msg, 'may be unavailable') != -1;
-END_MARK_TWO
-
- $code .= <<"END_MARK_THREE"; # Backwhack a lot!
- print "not ok: got unexpected warning \$msg\\n";
-} }
-
-{
- my \$test = $test;
- sub test (&) {
- my \$result = &{\$_[0]};
- print "not " unless \$result;
- print "ok \$test\\n";
- \$test++;
- }
-}
-
-# some of the variables which the closure will access
-\$global_scalar = 1000;
-\@global_array = (2000, 2100, 2200, 2300);
-%global_hash = 3000..3009;
-
-my \$fs_scalar = 4000;
-my \@fs_array = (5000, 5100, 5200, 5300);
-my %fs_hash = 6000..6009;
-
-END_MARK_THREE
-
- if ($where_declared eq 'filescope') {
- # Nothing here
- } elsif ($where_declared eq 'in_named') {
- $code .= <<'END';
-sub outer {
- my $sub_scalar = 7000;
- my @sub_array = (8000, 8100, 8200, 8300);
- my %sub_hash = 9000..9009;
-END
- # }
- } elsif ($where_declared eq 'in_anon') {
- $code .= <<'END';
-$outer = sub {
- my $sub_scalar = 7000;
- my @sub_array = (8000, 8100, 8200, 8300);
- my %sub_hash = 9000..9009;
-END
- # }
- } else {
- die "What was $where_declared?"
- }
-
- if ($within eq 'foreach') {
- $code .= "
- my \$foreach = 12000;
- my \@list = (10000, 10010);
- foreach \$foreach (\@list) {
- " # }
- } elsif ($within eq 'naked') {
- $code .= " { # naked block\n" # }
- } elsif ($within eq 'other_sub') {
- $code .= " sub inner_sub {\n" # }
- } else {
- die "What was $within?"
- }
-
- $sub_test = $test;
- @inners = ( qw!global_scalar global_array global_hash! ,
- qw!fs_scalar fs_array fs_hash! );
- push @inners, 'foreach' if $within eq 'foreach';
- if ($where_declared ne 'filescope') {
- push @inners, qw!sub_scalar sub_array sub_hash!;
- }
- for $inner_sub_test (@inners) {
-
- if ($inner_type eq 'named') {
- $code .= " sub named_$sub_test "
- } elsif ($inner_type eq 'anon') {
- $code .= " \$anon_$sub_test = sub "
- } else {
- die "What was $inner_type?"
- }
-
- # Now to write the body of the test sub
- if ($inner_sub_test eq 'global_scalar') {
- $code .= '{ ++$global_scalar }'
- } elsif ($inner_sub_test eq 'fs_scalar') {
- $code .= '{ ++$fs_scalar }'
- } elsif ($inner_sub_test eq 'sub_scalar') {
- $code .= '{ ++$sub_scalar }'
- } elsif ($inner_sub_test eq 'global_array') {
- $code .= '{ ++$global_array[1] }'
- } elsif ($inner_sub_test eq 'fs_array') {
- $code .= '{ ++$fs_array[1] }'
- } elsif ($inner_sub_test eq 'sub_array') {
- $code .= '{ ++$sub_array[1] }'
- } elsif ($inner_sub_test eq 'global_hash') {
- $code .= '{ ++$global_hash{3002} }'
- } elsif ($inner_sub_test eq 'fs_hash') {
- $code .= '{ ++$fs_hash{6002} }'
- } elsif ($inner_sub_test eq 'sub_hash') {
- $code .= '{ ++$sub_hash{9002} }'
- } elsif ($inner_sub_test eq 'foreach') {
- $code .= '{ ++$foreach }'
- } else {
- die "What was $inner_sub_test?"
- }
-
- # Close up
- if ($inner_type eq 'anon') {
- $code .= ';'
- }
- $code .= "\n";
- $sub_test++; # sub name sequence number
-
- } # End of foreach $inner_sub_test
-
- # Close up $within block # {
- $code .= " }\n\n";
-
- # Close up $where_declared block
- if ($where_declared eq 'in_named') { # {
- $code .= "}\n\n";
- } elsif ($where_declared eq 'in_anon') { # {
- $code .= "};\n\n";
- }
-
- # We may need to do something with the sub we just made...
- $code .= "undef \$outer;\n" if $undef_outer;
- $code .= "&inner_sub;\n" if $call_inner;
- if ($call_outer) {
- if ($where_declared eq 'in_named') {
- $code .= "&outer;\n\n";
- } elsif ($where_declared eq 'in_anon') {
- $code .= "&\$outer;\n\n"
- }
- }
-
- # Now, we can actually prep to run the tests.
- for $inner_sub_test (@inners) {
- $expected = $expected{$inner_sub_test} or
- die "expected $inner_sub_test missing";
-
- # Named closures won't access the expected vars
- if ( $nc_attempt and
- substr($inner_sub_test, 0, 4) eq "sub_" ) {
- $expected = 1;
- }
-
- # If you make a sub within a foreach loop,
- # what happens if it tries to access the
- # foreach index variable? If it's a named
- # sub, it gets the var from "outside" the loop,
- # but if it's anon, it gets the value to which
- # the index variable is aliased.
- #
- # Of course, if the value was set only
- # within another sub which was never called,
- # the value has not been set yet.
- #
- if ($inner_sub_test eq 'foreach') {
- if ($inner_type eq 'named') {
- if ($call_outer || ($where_declared eq 'filescope')) {
- $expected = 12001
- } else {
- $expected = 1
- }
- }
- }
-
- # Here's the test:
- if ($inner_type eq 'anon') {
- $code .= "test { &\$anon_$test == $expected };\n"
- } else {
- $code .= "test { &named_$test == $expected };\n"
- }
- $test++;
- }
-
- if ($Config{d_fork} and $^O ne 'VMS' and $^O ne 'MSWin32') {
- # Fork off a new perl to run the tests.
- # (This is so we can catch spurious warnings.)
- $| = 1; print ""; $| = 0; # flush output before forking
- pipe READ, WRITE or die "Can't make pipe: $!";
- pipe READ2, WRITE2 or die "Can't make second pipe: $!";
- die "Can't fork: $!" unless defined($pid = open PERL, "|-");
- unless ($pid) {
- # Child process here. We're going to send errors back
- # through the extra pipe.
- close READ;
- close READ2;
- open STDOUT, ">&WRITE" or die "Can't redirect STDOUT: $!";
- open STDERR, ">&WRITE2" or die "Can't redirect STDERR: $!";
- exec './perl', '-w', '-'
- or die "Can't exec ./perl: $!";
- } else {
- # Parent process here.
- close WRITE;
- close WRITE2;
- print PERL $code;
- close PERL;
- { local $/;
- $output = join '', <READ>;
- $errors = join '', <READ2>; }
- close READ;
- close READ2;
- }
- } else {
- # No fork(). Do it the hard way.
- my $cmdfile = "tcmd$$"; $cmdfile++ while -e $cmdfile;
- my $errfile = "terr$$"; $errfile++ while -e $errfile;
- my @tmpfiles = ($cmdfile, $errfile);
- open CMD, ">$cmdfile"; print CMD $code; close CMD;
- my $cmd = (($^O eq 'VMS') ? "MCR $^X"
- : ($^O eq 'MSWin32') ? '.\perl'
- : './perl');
- $cmd .= " -w $cmdfile 2>$errfile";
- if ($^O eq 'VMS' or $^O eq 'MSWin32') {
- # Use pipe instead of system so we don't inherit STD* from
- # this process, and then foul our pipe back to parent by
- # redirecting output in the child.
- open PERL,"$cmd |" or die "Can't open pipe: $!\n";
- { local $/; $output = join '', <PERL> }
- close PERL;
- } else {
- my $outfile = "tout$$"; $outfile++ while -e $outfile;
- push @tmpfiles, $outfile;
- system "$cmd >$outfile";
- { local $/; open IN, $outfile; $output = <IN>; close IN }
- }
- if ($?) {
- printf "not ok: exited with error code %04X\n", $?;
- $debugging or do { 1 while unlink @tmpfiles };
- exit;
- }
- { local $/; open IN, $errfile; $errors = <IN>; close IN }
- 1 while unlink @tmpfiles;
- }
- print $output;
- print STDERR $errors;
- if ($debugging && ($errors || $? || ($output =~ /not ok/))) {
- my $lnum = 0;
- for $line (split '\n', $code) {
- printf "%3d: %s\n", ++$lnum, $line;
- }
- }
- printf "not ok: exited with error code %04X\n", $? if $?;
- print "-" x 30, "\n" if $debugging;
-
- } # End of foreach $within
- } # End of foreach $where_declared
- } # End of foreach $inner_type
-
-}
-
OpenPOWER on IntegriCloud