summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorDavid Golden <dagolden@cpan.org>2010-11-28 23:12:12 -0500
committerDavid Golden <dagolden@cpan.org>2010-11-29 15:30:50 -0500
commit15e6cdd91beb4cefae4b65e855d68cf64766965d (patch)
tree9b22cf13e30a346c10c6dce7d2531d9e002e9d62 /gv.c
parenta812f6a926c0966af8d2a9a3d2d05fe1a5df510f (diff)
downloadperl-15e6cdd91beb4cefae4b65e855d68cf64766965d.tar.gz
Filehandle method calls load IO::File on demand
When a method call on a filehandle would die because the method can not be resolved and L<IO::File> has not been loaded, Perl now loads IO::File via C<require> and attempts method resolution again: open my $fh, ">", $file; $fh->binmode(":raw"); # loads IO::File and succeeds This also works for globs like STDOUT, STDERR and STDIN: STDOUT->autoflush(1); Because this on-demand load only happens if method resolution fails, the legacy approach of manually loading an IO::File parent class for partial method support still works as expected: use IO::Handle; open my $fh, ">", $file; $fh->autoflush(1); # IO::File not loaded
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/gv.c b/gv.c
index 5fd385bd11..4775bccf37 100644
--- a/gv.c
+++ b/gv.c
@@ -718,6 +718,19 @@ Perl_gv_fetchmethod_flags(pTHX_ HV *stash, const char *name, U32 flags)
/* Right now this is exclusively for the benefit of S_method_common
in pp_hot.c */
if (stash) {
+ /* If we can't find an IO::File method, it might be a call on
+ * a filehandle. If IO:File has not been loaded, try to
+ * require it first instead of croaking */
+ const char *stash_name = HvNAME_get(stash);
+ const char *io_file = "IO/File.pm";
+ if (stash_name && strEQ(stash_name,"IO::File")
+ && ! hv_exists(GvHVn(PL_incgv),io_file, strlen(io_file))
+ ) {
+ require_pv(io_file);
+ gv = gv_fetchmeth(stash, name, nend - name, 0);
+ if (gv)
+ return gv;
+ }
Perl_croak(aTHX_
"Can't locate object method \"%s\" via package \"%.*s\"",
name, (int)HvNAMELEN_get(stash), HvNAME_get(stash));