diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-12-17 23:01:07 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-12-17 23:19:04 -0800 |
commit | 8dc99089b7dd2506e907c4344ed28a3206866f37 (patch) | |
tree | 2b28cabfeba32d6a8fc290e622a14e7e0a99cc9b /t | |
parent | 8cd0c082aacc4c22b60ef4afdb96e244a082d4c1 (diff) | |
download | perl-8dc99089b7dd2506e907c4344ed28a3206866f37.tar.gz |
Stop tell($glob_copy) from clearing PL_last_in_gv
This bug is a side effect of rv2gv’s starting to return an incoercible
mortal copy of a coercible glob in 5.14:
$ perl5.12.4 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell'
0
$ perl5.14.0 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell'
-1
In the first case, tell without arguments is returning the position of
the filehandle.
In the second case, tell with an explicit argument that happens to
be a coercible glob (tell has an implicit rv2gv, so tell $fh is actu-
ally tell *$fh) sets PL_last_in_gv to a mortal copy thereof, which is
freed at the end of the statement, setting PL_last_in_gv to null. So
there is no ‘last used’ handle by the time we get to the tell without
arguments.
This commit adds a new rv2gv flag that tells it not to copy the glob.
By doing it unconditionally on the kidop, this allows tell(*$fh) to
work the same way.
Let’s hope nobody does tell(*{*$fh}), which will unset PL_last_in_gv
because the inner * returns a mortal copy.
This whole area is really icky. PL_last_in_gv should be refcounted,
but that would cause handles to leak out of scope, breaking programs
that rely on the auto-closing ‘feature’.
Diffstat (limited to 't')
-rw-r--r-- | t/io/tell.t | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/t/io/tell.t b/t/io/tell.t index 8e4f14e55d..5fe65b3a0f 100644 --- a/t/io/tell.t +++ b/t/io/tell.t @@ -6,7 +6,7 @@ BEGIN { require './test.pl'; } -print "1..28\n"; +print "1..31\n"; $TST = 'TST'; @@ -160,3 +160,12 @@ if (tell($tst) == 6) { print "ok 28$todo\n"; } else { print "not ok 28$todo\n"; } close $tst; +open FH, "test.pl"; +$fh = *FH; # coercible glob +$not = "not " x! (tell $fh == 0); +print "${not}ok 29 - tell on coercible glob\n"; +$not = "not " x! (tell == 0); +print "${not}ok 30 - argless tell after tell \$coercible\n"; +tell *$fh; +$not = "not " x! (tell == 0); +print "${not}ok 31 - argless tell after tell *\$coercible\n"; |