summaryrefslogtreecommitdiff
path: root/perl.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-02-06 17:55:32 -0800
committerJesse Vincent <jesse@bestpractical.com>2010-02-06 18:02:34 -0800
commitd963bf01c4c4db296760b1148f98bf668efcaf58 (patch)
tree2cb11035e6ab5271b3ec9c18f6f33f980afc0003 /perl.c
parent23d72198749db53785b1c67cd1a37697afb95fc0 (diff)
downloadperl-d963bf01c4c4db296760b1148f98bf668efcaf58.tar.gz
Improvements to 31c9a3 - CPAN code did depend on the previous behaviour of blessing filehandles into FileHandle
It turns out that it's not quite as simple as blessing into IO::File. If you do (just) that, then it breaks any existing code that does C<require IO::Handle;> to allow it to call methods on file handles, because they're blessed into IO::File, which isn't loaded. (Note this code doesn't assume that methods in IO::Seekable are there to be called) So, it all should work if you also set @IO::File:::ISA correctly? That way, code that assumes that methods from IO::Handle can be called will work. However, gv.c now starts complaining (but not failing) if IO::Handle, IO::Seekable and Exporter aren't present, because it goes looking for methods in them. So the solution seems to be to set @IO::File::ISA *and* create (empty) stashes for the other 3 packages. Patch appended, but not applied.
Diffstat (limited to 'perl.c')
-rw-r--r--perl.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/perl.c b/perl.c
index 9f7e831db5..04184be040 100644
--- a/perl.c
+++ b/perl.c
@@ -3863,10 +3863,34 @@ S_init_predump_symbols(pTHX)
dVAR;
GV *tmpgv;
IO *io;
+ AV *isa;
sv_setpvs(get_sv("\"", GV_ADD), " ");
PL_ofsgv = (GV*)SvREFCNT_inc(gv_fetchpvs(",", GV_ADD|GV_NOTQUAL, SVt_PV));
+
+ /* Historically, PVIOs were blessed into IO::Handle, unless
+ FileHandle was loaded, in which case they were blessed into
+ that. Action at a distance.
+ However, if we simply bless into IO::Handle, we break code
+ that assumes that PVIOs will have (among others) a seek
+ method. IO::File inherits from IO::Handle and IO::Seekable,
+ and provides the needed methods. But if we simply bless into
+ it, then we break code that assumed that by loading
+ IO::Handle, *it* would work.
+ So a compromise is to set up the correct @IO::File::ISA,
+ so that code that does C<use IO::Handle>; will still work.
+ */
+
+ isa = get_av("IO::File::ISA", GV_ADD | GV_ADDMULTI);
+ av_push(isa, newSVpvs("IO::Handle"));
+ av_push(isa, newSVpvs("IO::Seekable"));
+ av_push(isa, newSVpvs("Exporter"));
+ (void) gv_fetchpvs("IO::Handle::", GV_ADD, SVt_PVGV);
+ (void) gv_fetchpvs("IO::Seekable::", GV_ADD, SVt_PVGV);
+ (void) gv_fetchpvs("Exporter::", GV_ADD, SVt_PVGV);
+
+
PL_stdingv = gv_fetchpvs("STDIN", GV_ADD|GV_NOTQUAL, SVt_PVIO);
GvMULTI_on(PL_stdingv);
io = GvIOp(PL_stdingv);