develooper Front page | perl.perl5.porters | Postings from April 2006

Re: Bug or Limitation: "Filehandles" in pp_require

Thread Previous
From:
Nicholas Clark
Date:
April 14, 2006 08:56
Subject:
Re: Bug or Limitation: "Filehandles" in pp_require
Message ID:
20060414155636.GP32132@plum.flirble.org
Quoting the whole lot because it's rather old, and all relevant:

On Tue, Nov 15, 2005 at 10:27:43AM +0100, Jos I. Boumans wrote:
> Hi,
> 
> in the course of events, I found myself needing to dynamically append 
> some code to
> an existing file, before executing it. The 'usual' solution of an @INC 
> hook came to
> mind. However, not every hook behaved in the way i expected. Given this 
> code:
> 
> 	$ perl -Mx -e'use ExistsNot'
> 
> I use x.pm to set up an @INC handler as follows, to allow ExistsNot to 
> be loaded:
> 
>     ### file x.pm ###
>     BEGIN {
>         use IO::String;
>         use Tie::Handle;
>         use Devel::Peek;
>         use PerlIO;
>         use File::Temp  qw[tempfile];
> 
>         my $Str = "package ExistsNot; 1;\n";
> 
>         unshift @INC,
>             sub {   warn "Code ref 1 -- IO::String\n";
>                     my $io = IO::String->new;
>                     $io->print( $Str );
>                     #Dump( $io );
>                     $io->setpos(0);
>                     return $io;
>             },
>             sub {   warn "Code ref 2 -- Tie::Handle\n";
>                     package X;
>                     @ISA = qw[Tie::StdHandle];
>                     sub READLINE  { $Str };
>                     tie *FH, 'X';
>                     #Devel::Peek::Dump( \*FH );
>                     return \*FH;
>             },
>             sub {   warn "Code ref 3 -- PerlIO";
>                     my $dummy = "";
>                     open my $fh, '>', \$dummy   or die $!;
>                     print $fh $Str              or die $!;
>                     seek $fh, 0, 0;
>                     #Dump( $fh );
>                     return $fh;
>             },
>             sub {   warn "Code ref 4 -- File::Temp\n";
>                     my($fh,$name) = tempfile();
>                     print $fh $Str;
>                     close $fh;
>                     open my $fh2, $name or warn $!;
>                     #Dump( $fh2 );
>                     return $fh2;
>             },
>             sub {   die "Code ref 5 -- failed to load\n" },
>     }
> 
>     1;
> 
> 
> It turns out that only code ref 3 and 4 are able to produce a 
> filehandle accepted by
> pp_require, whereas 1 and 2 will not. Looking at the pp_require code in 
> pp_ctl.c, i see
> the following:
> 
>     else {
>         if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
>             PerlIO_close(IoOFP(io));
>         }
>         IoIFP(io) = Nullfp;
>         IoOFP(io) = Nullfp;
>     }
> 
> which looks like a direct access to the file, rather than using any 
> magic or interface
> that's been defined for this value. Not quite what i expected, and not 
> documented it seems.
> 
> Should this be fixed, or noted as a known shortcoming in some relevant 
> pod file?

I think it should be documented. As you observe, only references 3 and 4
produce real file handles, and the reads done in toke.c are direct on C level
C<PerlIO*>s, rather than Perl ops on Perl file handles (which would take tie
into account).

Currently it's actually possible to produce a generator without needing
a file handle:

#!perl
use warnings;
use strict;

BEGIN {
    push @INC, sub {
        return unless $_[1] =~ /pie/i;
        my $state;
        sub {
            return -1 if $state++;
            $_ = 'warn "Pie!"; 1;';
            1;
        }
    }
}

use Pie;
use Carp;
carp "Hi";
__END__
Pie! at /loader/0x827df4c/Pie.pm line 1.
Hi at testfilter.pl line 18


which isn't documented. This is part of the undocumented return values for
@INC hooks. For the TPF grant I had said that the undocumented parts should
be replaced with something using Filter::Simple. I'm now having ideas that a
variant would be better - I'll mail p5p in a new thread.

Nicholas Clark

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About