1#!./perl 2# -*- Mode: Perl -*- 3# closure.t: 4# Original written by Ulrich Pfeifer on 2 Jan 1997. 5# Greatly extended by Tom Phoenix <rootbeer@teleport.com> on 28 Jan 1997. 6# 7# Run with -debug for debugging output. 8 9BEGIN { 10 chdir 't' if -d 't'; 11 require './test.pl'; 12 set_up_inc('../lib'); 13} 14 15use Config; 16 17my $i = 1; 18sub foo { $i = shift if @_; $i } 19 20# no closure 21is(foo, 1); 22foo(2); 23is(foo, 2); 24 25# closure: lexical outside sub 26my $foo = sub {$i = shift if @_; $i }; 27my $bar = sub {$i = shift if @_; $i }; 28is(&$foo(), 2); 29&$foo(3); 30is(&$foo(), 3); 31# did the lexical change? 32is(foo, 3, 'lexical changed'); 33is($i, 3, 'lexical changed'); 34# did the second closure notice? 35is(&$bar(), 3, 'second closure noticed'); 36 37# closure: lexical inside sub 38sub bar { 39 my $i = shift; 40 sub { $i = shift if @_; $i } 41} 42 43$foo = bar(4); 44$bar = bar(5); 45is(&$foo(), 4); 46&$foo(6); 47is(&$foo(), 6); 48is(&$bar(), 5); 49 50# nested closures 51sub bizz { 52 my $i = 7; 53 if (@_) { 54 my $i = shift; 55 sub {$i = shift if @_; $i }; 56 } else { 57 my $i = $i; 58 sub {$i = shift if @_; $i }; 59 } 60} 61$foo = bizz(); 62$bar = bizz(); 63is(&$foo(), 7); 64&$foo(8); 65is(&$foo(), 8); 66is(&$bar(), 7); 67 68$foo = bizz(9); 69$bar = bizz(10); 70is(&$foo(11)-1, &$bar()); 71 72my @foo; 73for (qw(0 1 2 3 4)) { 74 my $i = $_; 75 $foo[$_] = sub {$i = shift if @_; $i }; 76} 77 78is(&{$foo[0]}(), 0); 79is(&{$foo[1]}(), 1); 80is(&{$foo[2]}(), 2); 81is(&{$foo[3]}(), 3); 82is(&{$foo[4]}(), 4); 83 84for (0 .. 4) { 85 &{$foo[$_]}(4-$_); 86} 87 88is(&{$foo[0]}(), 4); 89is(&{$foo[1]}(), 3); 90is(&{$foo[2]}(), 2); 91is(&{$foo[3]}(), 1); 92is(&{$foo[4]}(), 0); 93 94sub barf { 95 my @foo; 96 for (qw(0 1 2 3 4)) { 97 my $i = $_; 98 $foo[$_] = sub {$i = shift if @_; $i }; 99 } 100 @foo; 101} 102 103@foo = barf(); 104is(&{$foo[0]}(), 0); 105is(&{$foo[1]}(), 1); 106is(&{$foo[2]}(), 2); 107is(&{$foo[3]}(), 3); 108is(&{$foo[4]}(), 4); 109 110for (0 .. 4) { 111 &{$foo[$_]}(4-$_); 112} 113 114is(&{$foo[0]}(), 4); 115is(&{$foo[1]}(), 3); 116is(&{$foo[2]}(), 2); 117is(&{$foo[3]}(), 1); 118is(&{$foo[4]}(), 0); 119 120# test if closures get created in optimized for loops 121 122my %foo; 123for my $n ('A'..'E') { 124 $foo{$n} = sub { $n eq $_[0] }; 125} 126 127ok(&{$foo{A}}('A')); 128ok(&{$foo{B}}('B')); 129ok(&{$foo{C}}('C')); 130ok(&{$foo{D}}('D')); 131ok(&{$foo{E}}('E')); 132 133for my $n (0..4) { 134 $foo[$n] = sub { $n == $_[0] }; 135} 136 137ok(&{$foo[0]}(0)); 138ok(&{$foo[1]}(1)); 139ok(&{$foo[2]}(2)); 140ok(&{$foo[3]}(3)); 141ok(&{$foo[4]}(4)); 142 143for my $n (0..4) { 144 $foo[$n] = sub { 145 # no intervening reference to $n here 146 sub { $n == $_[0] } 147 }; 148} 149 150ok($foo[0]->()->(0)); 151ok($foo[1]->()->(1)); 152ok($foo[2]->()->(2)); 153ok($foo[3]->()->(3)); 154ok($foo[4]->()->(4)); 155 156{ 157 my $w; 158 $w = sub { 159 my ($i) = @_; 160 is($i, 10); 161 sub { $w }; 162 }; 163 $w->(10); 164} 165 166# Additional tests by Tom Phoenix <rootbeer@teleport.com>. 167 168{ 169 use strict; 170 171 our $test; 172 my($debugging, %expected, $inner_type, $where_declared, $within); 173 my($nc_attempt, $call_outer, $call_inner, $undef_outer); 174 my($code, $inner_sub_test, $expected, $line, $errors, $output); 175 my(@inners, $sub_test, $pid); 176 $debugging = 1 if defined($ARGV[0]) and $ARGV[0] eq '-debug'; 177 178 # The expected values for these tests 179 %expected = ( 180 'global_scalar' => 1001, 181 'global_array' => 2101, 182 'global_hash' => 3004, 183 'fs_scalar' => 4001, 184 'fs_array' => 5101, 185 'fs_hash' => 6004, 186 'sub_scalar' => 7001, 187 'sub_array' => 8101, 188 'sub_hash' => 9004, 189 'foreach' => 10011, 190 ); 191 192 # Our innermost sub is either named or anonymous 193 for $inner_type (qw!named anon!) { 194 # And it may be declared at filescope, within a named 195 # sub, or within an anon sub 196 for $where_declared (qw!filescope in_named in_anon!) { 197 # And that, in turn, may be within a foreach loop, 198 # a naked block, or another named sub 199 for $within (qw!foreach naked other_sub!) { 200 201 my $test = curr_test(); 202 # Here are a number of variables which show what's 203 # going on, in a way. 204 $nc_attempt = 0+ # Named closure attempted 205 ( ($inner_type eq 'named') || 206 ($within eq 'other_sub') ) ; 207 $call_inner = 0+ # Need to call &inner 208 ( ($inner_type eq 'anon') && 209 ($within eq 'other_sub') ) ; 210 $call_outer = 0+ # Need to call &outer or &$outer 211 ( ($inner_type eq 'anon') && 212 ($within ne 'other_sub') ) ; 213 $undef_outer = 0+ # $outer is created but unused 214 ( ($where_declared eq 'in_anon') && 215 (not $call_outer) ) ; 216 217 $code = "# This is a test script built by t/op/closure.t\n\n"; 218 219 print <<"DEBUG_INFO" if $debugging; 220# inner_type: $inner_type 221# where_declared: $where_declared 222# within: $within 223# nc_attempt: $nc_attempt 224# call_inner: $call_inner 225# call_outer: $call_outer 226# undef_outer: $undef_outer 227DEBUG_INFO 228 229 $code .= <<"END_MARK_ONE"; 230 231BEGIN { \$SIG{__WARN__} = sub { 232 my \$msg = \$_[0]; 233END_MARK_ONE 234 235 $code .= <<"END_MARK_TWO" if $nc_attempt; 236 return if index(\$msg, 'will not stay shared') != -1; 237 return if index(\$msg, 'is not available') != -1; 238END_MARK_TWO 239 240 $code .= <<"END_MARK_THREE"; # Backwhack a lot! 241 print "not ok: got unexpected warning \$msg\\n"; 242} } 243 244require './test.pl'; 245curr_test($test); 246 247# some of the variables which the closure will access 248\$global_scalar = 1000; 249\@global_array = (2000, 2100, 2200, 2300); 250%global_hash = 3000..3009; 251 252my \$fs_scalar = 4000; 253my \@fs_array = (5000, 5100, 5200, 5300); 254my %fs_hash = 6000..6009; 255 256END_MARK_THREE 257 258 if ($where_declared eq 'filescope') { 259 # Nothing here 260 } elsif ($where_declared eq 'in_named') { 261 $code .= <<'END'; 262sub outer { 263 my $sub_scalar = 7000; 264 my @sub_array = (8000, 8100, 8200, 8300); 265 my %sub_hash = 9000..9009; 266END 267 # } 268 } elsif ($where_declared eq 'in_anon') { 269 $code .= <<'END'; 270$outer = sub { 271 my $sub_scalar = 7000; 272 my @sub_array = (8000, 8100, 8200, 8300); 273 my %sub_hash = 9000..9009; 274END 275 # } 276 } else { 277 die "What was $where_declared?" 278 } 279 280 if ($within eq 'foreach') { 281 $code .= " 282 my \$foreach = 12000; 283 my \@list = (10000, 10010); 284 foreach \$foreach (\@list) { 285 " # } 286 } elsif ($within eq 'naked') { 287 $code .= " { # naked block\n" # } 288 } elsif ($within eq 'other_sub') { 289 $code .= " sub inner_sub {\n" # } 290 } else { 291 die "What was $within?" 292 } 293 294 $sub_test = $test; 295 @inners = ( qw!global_scalar global_array global_hash! , 296 qw!fs_scalar fs_array fs_hash! ); 297 push @inners, 'foreach' if $within eq 'foreach'; 298 if ($where_declared ne 'filescope') { 299 push @inners, qw!sub_scalar sub_array sub_hash!; 300 } 301 for $inner_sub_test (@inners) { 302 303 if ($inner_type eq 'named') { 304 $code .= " sub named_$sub_test " 305 } elsif ($inner_type eq 'anon') { 306 $code .= " \$anon_$sub_test = sub " 307 } else { 308 die "What was $inner_type?" 309 } 310 311 # Now to write the body of the test sub 312 if ($inner_sub_test eq 'global_scalar') { 313 $code .= '{ ++$global_scalar }' 314 } elsif ($inner_sub_test eq 'fs_scalar') { 315 $code .= '{ ++$fs_scalar }' 316 } elsif ($inner_sub_test eq 'sub_scalar') { 317 $code .= '{ ++$sub_scalar }' 318 } elsif ($inner_sub_test eq 'global_array') { 319 $code .= '{ ++$global_array[1] }' 320 } elsif ($inner_sub_test eq 'fs_array') { 321 $code .= '{ ++$fs_array[1] }' 322 } elsif ($inner_sub_test eq 'sub_array') { 323 $code .= '{ ++$sub_array[1] }' 324 } elsif ($inner_sub_test eq 'global_hash') { 325 $code .= '{ ++$global_hash{3002} }' 326 } elsif ($inner_sub_test eq 'fs_hash') { 327 $code .= '{ ++$fs_hash{6002} }' 328 } elsif ($inner_sub_test eq 'sub_hash') { 329 $code .= '{ ++$sub_hash{9002} }' 330 } elsif ($inner_sub_test eq 'foreach') { 331 $code .= '{ ++$foreach }' 332 } else { 333 die "What was $inner_sub_test?" 334 } 335 336 # Close up 337 if ($inner_type eq 'anon') { 338 $code .= ';' 339 } 340 $code .= "\n"; 341 $sub_test++; # sub name sequence number 342 343 } # End of foreach $inner_sub_test 344 345 # Close up $within block # { 346 $code .= " }\n\n"; 347 348 # Close up $where_declared block 349 if ($where_declared eq 'in_named') { # { 350 $code .= "}\n\n"; 351 } elsif ($where_declared eq 'in_anon') { # { 352 $code .= "};\n\n"; 353 } 354 355 # We may need to do something with the sub we just made... 356 $code .= "undef \$outer;\n" if $undef_outer; 357 $code .= "&inner_sub;\n" if $call_inner; 358 if ($call_outer) { 359 if ($where_declared eq 'in_named') { 360 $code .= "&outer;\n\n"; 361 } elsif ($where_declared eq 'in_anon') { 362 $code .= "&\$outer;\n\n" 363 } 364 } 365 366 # Now, we can actually prep to run the tests. 367 for $inner_sub_test (@inners) { 368 $expected = $expected{$inner_sub_test} or 369 die "expected $inner_sub_test missing"; 370 371 # Named closures won't access the expected vars 372 if ( $nc_attempt and 373 substr($inner_sub_test, 0, 4) eq "sub_" ) { 374 $expected = 1; 375 } 376 377 # If you make a sub within a foreach loop, 378 # what happens if it tries to access the 379 # foreach index variable? If it's a named 380 # sub, it gets the var from "outside" the loop, 381 # but if it's anon, it gets the value to which 382 # the index variable is aliased. 383 # 384 # Of course, if the value was set only 385 # within another sub which was never called, 386 # the value has not been set yet. 387 # 388 if ($inner_sub_test eq 'foreach') { 389 if ($inner_type eq 'named') { 390 if ($call_outer || ($where_declared eq 'filescope')) { 391 $expected = 12001 392 } else { 393 $expected = 1 394 } 395 } 396 } 397 398 # Here's the test: 399 my $desc = "$inner_type $where_declared $within $inner_sub_test"; 400 if ($inner_type eq 'anon') { 401 $code .= "is(&\$anon_$test, $expected, '$desc');\n" 402 } else { 403 $code .= "is(&named_$test, $expected, '$desc');\n" 404 } 405 $test++; 406 } 407 408 if ($Config{d_fork} and $^O ne 'VMS' and $^O ne 'MSWin32') { 409 # Fork off a new perl to run the tests. 410 # (This is so we can catch spurious warnings.) 411 $| = 1; print ""; $| = 0; # flush output before forking 412 pipe READ, WRITE or die "Can't make pipe: $!"; 413 pipe READ2, WRITE2 or die "Can't make second pipe: $!"; 414 die "Can't fork: $!" unless defined($pid = open PERL, "|-"); 415 unless ($pid) { 416 # Child process here. We're going to send errors back 417 # through the extra pipe. 418 close READ; 419 close READ2; 420 open STDOUT, ">&WRITE" or die "Can't redirect STDOUT: $!"; 421 open STDERR, ">&WRITE2" or die "Can't redirect STDERR: $!"; 422 exec which_perl(), '-w', '-' 423 or die "Can't exec perl: $!"; 424 } else { 425 # Parent process here. 426 close WRITE; 427 close WRITE2; 428 print PERL $code; 429 close PERL; 430 { local $/; 431 $output = join '', <READ>; 432 $errors = join '', <READ2>; } 433 close READ; 434 close READ2; 435 } 436 } else { 437 # No fork(). Do it the hard way. 438 my $cmdfile = tempfile(); 439 my $errfile = tempfile(); 440 open CMD, ">$cmdfile"; print CMD $code; close CMD; 441 my $cmd = which_perl(); 442 $cmd .= " -w $cmdfile 2>$errfile"; 443 if ($^O eq 'VMS' or $^O eq 'MSWin32') { 444 # Use pipe instead of system so we don't inherit STD* from 445 # this process, and then foul our pipe back to parent by 446 # redirecting output in the child. 447 open PERL,"$cmd |" or die "Can't open pipe: $!\n"; 448 { local $/; $output = join '', <PERL> } 449 close PERL; 450 } else { 451 my $outfile = tempfile(); 452 system "$cmd >$outfile"; 453 { local $/; open IN, $outfile; $output = <IN>; close IN } 454 } 455 if ($?) { 456 printf "not ok: exited with error code %04X\n", $?; 457 exit; 458 } 459 { local $/; open IN, $errfile; $errors = <IN>; close IN } 460 } 461 print $output; 462 curr_test($test); 463 print STDERR $errors; 464 # This has the side effect of alerting *our* test.pl to the state of 465 # what has just been passed to STDOUT, so that if anything there has 466 # failed, our test.pl will print a diagnostic and exit uncleanly. 467 unlike($output, qr/not ok/, 'All good'); 468 is($errors, '', 'STDERR is silent'); 469 if ($debugging && ($errors || $? || ($output =~ /not ok/))) { 470 my $lnum = 0; 471 for $line (split '\n', $code) { 472 printf "%3d: %s\n", ++$lnum, $line; 473 } 474 } 475 is($?, 0, 'exited cleanly') or diag(sprintf "Error code $? = 0x%X", $?); 476 print '#', "-" x 30, "\n" if $debugging; 477 478 } # End of foreach $within 479 } # End of foreach $where_declared 480 } # End of foreach $inner_type 481 482} 483 484# The following dumps core with perl <= 5.8.0 (bugid 9535) ... 485BEGIN { $vanishing_pad = sub { eval $_[0] } } 486$some_var = 123; 487is($vanishing_pad->('$some_var'), 123, 'RT #9535'); 488 489# ... and here's another coredump variant - this time we explicitly 490# delete the sub rather than using a BEGIN ... 491 492sub deleteme { $a = sub { eval '$newvar' } } 493deleteme(); 494*deleteme = sub {}; # delete the sub 495$newvar = 123; # realloc the SV of the freed CV 496is($a->(), 123, 'RT #9535'); 497 498# ... and a further coredump variant - the fixup of the anon sub's 499# CvOUTSIDE pointer when the middle eval is freed, wasn't good enough to 500# survive the outer eval also being freed. 501 502$x = 123; 503$a = eval q( 504 eval q[ 505 sub { eval '$x' } 506 ] 507); 508@a = ('\1\1\1\1\1\1\1') x 100; # realloc recently-freed CVs 509is($a->(), 123, 'RT #9535'); 510 511# this coredumped on <= 5.8.0 because evaling the closure caused 512# an SvFAKE to be added to the outer anon's pad, which was then grown. 513my $outer; 514sub { 515 my $x; 516 $x = eval 'sub { $outer }'; 517 $x->(); 518 $a = [ 99 ]; 519 $x->(); 520}->(); 521pass(); 522 523# [perl #17605] found that an empty block called in scalar context 524# can lead to stack corruption 525{ 526 my $x = "foooobar"; 527 $x =~ s/o//eg; 528 is($x, 'fbar', 'RT #17605'); 529} 530 531# DAPM 24-Nov-02 532# SvFAKE lexicals should be visible thoughout a function. 533# On <= 5.8.0, the third test failed, eg bugid #18286 534 535{ 536 my $x = 1; 537 sub fake { 538 is(sub {eval'$x'}->(), 1, 'RT #18286'); 539 { $x; is(sub {eval'$x'}->(), 1, 'RT #18286'); } 540 is(sub {eval'$x'}->(), 1, 'RT #18286'); 541 } 542} 543fake(); 544 545{ 546 $x = 1; 547 my $x = 2; 548 sub tmp { sub { eval '$x' } } 549 my $a = tmp(); 550 undef &tmp; 551 is($a->(), 2, 552 "undefining a sub shouldn't alter visibility of outer lexicals"); 553} 554 555# handy class: $x = Watch->new(\$foo,'bar') 556# causes 'bar' to be appended to $foo when $x is destroyed 557sub Watch::new { bless [ $_[1], $_[2] ], $_[0] } 558sub Watch::DESTROY { ${$_[0][0]} .= $_[0][1] } 559 560# bugid 1028: 561# nested anon subs (and associated lexicals) not freed early enough 562 563sub linger { 564 my $x = Watch->new($_[0], '2'); 565 sub { 566 $x; 567 my $y; 568 sub { $y; }; 569 }; 570} 571{ 572 my $watch = '1'; 573 linger(\$watch); 574 is($watch, '12', 'RT #1028'); 575} 576 577# bugid 10085 578# obj not freed early enough 579 580sub linger2 { 581 my $obj = Watch->new($_[0], '2'); 582 sub { sub { $obj } }; 583} 584{ 585 my $watch = '1'; 586 linger2(\$watch); 587 is($watch, 12, 'RT #10085'); 588} 589 590# bugid 16302 - named subs didn't capture lexicals on behalf of inner subs 591 592{ 593 my $x = 1; 594 sub f16302 { 595 sub { 596 is($x, 1, 'RT #16302'); 597 }->(); 598 } 599} 600f16302(); 601 602# The presence of an eval should turn cloneless anon subs into clonable 603# subs - otherwise the CvOUTSIDE of that sub may be wrong 604 605{ 606 my %a; 607 for my $x (7,11) { 608 $a{$x} = sub { $x=$x; sub { eval '$x' } }; 609 } 610 is($a{7}->()->() + $a{11}->()->(), 18); 611} 612 613{ 614 # bugid #23265 - this used to coredump during destruction of PL_main_cv 615 # and its children 616 617 fresh_perl_is(<< '__EOF__', "yxx\n", {stderr => 1}, 'RT #23265'); 618 print 619 sub {$_[0]->(@_)} -> ( 620 sub { 621 $_[1] 622 ? $_[0]->($_[0], $_[1] - 1) . sub {"x"}->() 623 : "y" 624 }, 625 2 626 ) 627 , "\n" 628 ; 629__EOF__ 630} 631 632{ 633 # bugid #24914 = used to coredump restoring PL_comppad in the 634 # savestack, due to the early freeing of the anon closure 635 636 fresh_perl_is('sub d {die} my $f; $f = sub {my $x=1; $f = 0; d}; eval{$f->()}; print qq(ok\n)', 637 "ok\n", {stderr => 1}, 'RT #24914'); 638} 639 640 641# After newsub is redefined outside the BEGIN, its CvOUTSIDE should point 642# to main rather than BEGIN, and BEGIN should be freed. 643 644{ 645 my $flag = 0; 646 sub X::DESTROY { $flag = 1 } 647 { 648 my $x; 649 BEGIN {$x = \&newsub } 650 sub newsub {}; 651 $x = bless {}, 'X'; 652 } 653 is($flag, 1); 654} 655 656sub f { 657 my $x; 658 format ff = 659@ 660$r = \$x 661. 662} 663 664{ 665 fileno ff; 666 write ff; 667 my $r1 = $r; 668 write ff; 669 my $r2 = $r; 670 isnt($r1, $r2, 671 "don't copy a stale lexical; create a fresh undef one instead"); 672} 673 674# test PL_cv_has_eval. Any anon sub that could conceivably contain an 675# eval, should be marked as cloneable 676 677{ 678 679 my @s; 680 push @s, sub { eval '1' } for 1,2; 681 isnt($s[0], $s[1], "cloneable with eval"); 682 @s = (); 683 push @s, sub { use re 'eval'; my $x; s/$x/1/; } for 1,2; 684 isnt($s[0], $s[1], "cloneable with use re eval"); 685 @s = (); 686 push @s, sub { s/1/1/ee; } for 1,2; 687 isnt($s[0], $s[1], "cloneable with //ee"); 688} 689 690# [perl #89544] 691{ 692 sub trace::DESTROY { 693 push @trace::trace, "destroyed"; 694 } 695 696 my $outer2 = sub { 697 my $a = bless \my $dummy, trace::; 698 699 my $outer = sub { 700 my $b; 701 my $inner = sub { 702 undef $b; 703 }; 704 705 $a; 706 707 $inner 708 }; 709 710 $outer->() 711 }; 712 713 my $inner = $outer2->(); 714 is "@trace::trace", "destroyed", 715 'closures only close over named variables, not entire subs'; 716} 717 718# [perl #113812] Closure prototypes with no CvOUTSIDE (crash caused by the 719# fix for #89544) 720do "./op/closure_test.pl" or die $@||$!; 721is $closure_test::s2->()(), '10 cubes', 722 'cloning closure proto with no CvOUTSIDE'; 723 724# Also brought up in #113812: Even when being cloned, a closure prototype 725# might have its CvOUTSIDE pointing to the wrong thing. 726{ 727 package main::113812; 728 $s1 = sub { 729 my $x = 3; 730 $s2 = sub { 731 $x; 732 $s3 = sub { $x }; 733 }; 734 }; 735 $s1->(); 736 undef &$s1; # frees $s2's prototype, causing the $s3 proto to have its 737 # CvOUTSIDE point to $s1 738 ::is $s2->()(), 3, 'cloning closure proto whose CvOUTSIDE has changed'; 739} 740 741# This should never emit two different values: 742# print $x, "\n"; 743# print sub { $x }->(), "\n"; 744# This test case started to do just that in commit 33894c1aa3e 745# (5.10.1/5.12.0): 746sub mosquito { 747 my $x if @_; 748 return if @_; 749 750 $x = 17; 751 is sub { $x }->(), $x, 'closing over stale var in 2nd sub call'; 752} 753mosquito(1); 754mosquito; 755# And this case in commit adf8f095c588 (5.14): 756sub anything { 757 my $x; 758 sub gnat { 759 $x = 3; 760 is sub { $x }->(), $x, 761 'closing over stale var before 1st sub call'; 762 } 763} 764gnat(); 765 766# [perl #114018] Similar to the above, but with string eval 767sub staleval { 768 my $x if @_; 769 return if @_; 770 771 $x = 3; 772 is eval '$x', $x, 'eval closing over stale var in active sub'; 773 return # 774} 775staleval 1; 776staleval; 777 778# [perl #114888] 779# Test that closure creation localises PL_comppad_name properly. Usually 780# at compile time a BEGIN block will localise PL_comppad_name for use, so 781# pp_anoncode can mess with it without any visible effects. 782# But inside a source filter, it affects the directly enclosing compila- 783# tion scope. 784SKIP: { 785 skip_if_miniperl("no XS on miniperl (for source filters)"); 786 fresh_perl_is <<' [perl #114888]', "ok\n", {stderr=>1}, 787 use strict; 788 BEGIN { 789 package Foo; 790 use Filter::Util::Call; 791 sub import { filter_add( sub { 792 my $status = filter_read(); 793 sub { $status }; 794 $status; 795 })} 796 Foo->import 797 } 798 my $x = "ok\n"; # stores $x in the wrong padnamelist 799 print $x; # cannot find it - strict violation 800 [perl #114888] 801 'closures in source filters do not interfere with pad names'; 802} 803 804sub { 805 my $f; 806 sub test_ref_to_unavailable { 807 my $ref = \$f; 808 $$ref = 7; 809 is $f, 7, 'taking a ref to unavailable var should not copy it'; 810 } 811}; 812test_ref_to_unavailable(); 813 814done_testing(); 815