http://qs1969.pair.com?node_id=1154437


in reply to Introspecting the current Perl file via DATA, even w/o DATA?

I'm pretty sure that DATA is only an alias of anther filehandle pointing to the current code...
Why do you think so? It seems such a thing doesn't exist:
for ( values %main:: ) { my $io = *{$_}{IO} or next; my $name = *{$_}{NAME}; if ( defined fileno $io ) { printf "fileno of %6s is %d\n", $name, fileno $io; } else { print "($name is a virtual handle)\n"; } }
output:
fileno of stdin is 0 fileno of stdout is 1 fileno of STDIN is 0 fileno of STDOUT is 1 fileno of stderr is 2 fileno of STDERR is 2 (ARGV is a virtual handle)
and if we add __DATA__ to the file:
fileno of STDERR is 2 fileno of STDIN is 0 fileno of STDOUT is 1 fileno of stdout is 1 fileno of stdin is 0 (ARGV is a virtual handle) fileno of DATA is 3 fileno of stderr is 2
So only __DATA__ is opened on fd 3... maybe there is some secret pro tech, but I suspect there isn't and then your best option is probably to just open __FILE__

Replies are listed 'Best First'.
Re^2: Introspecting the current Perl file via DATA, even w/o DATA?
by LanX (Saint) on Feb 05, 2016 at 01:13 UTC
    > Why do you think so?

    Because the filepointer is in sync with the parsing phases of Perl. There is an explicit warning not to read DATA at BEGIN or use phases because the end of file isn't reached yet.

    And testing showed that in this cases you can readline the currently processed source line resp. the next one.

    Not finding the handle in the main stash doesn't mean it doesn't exist somewhere else (probably hidden somewhere in B )

    update
    • Using a neutral source filter might be another option to fill @lines ...
    • IIRC is the debugger keeping the content source files in similar arrays, maybe I should have again a look into perl5db.pl.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      Because the filepointer is in sync with the parsing phases of Perl
      Not necessarily, no... Let's see
      BEGIN { print "BEGIN\n"; } UNITCHECK { print "UNITCHECK\n"; } CHECK { print "CHECK\n"; } INIT { print "INIT\n"; } print "MAIN\n";
      Let's strace it (Debian Jessie, Perl 5.22)
      open("t.pl", O_RDONLY) = 3 ... read(3, "BEGIN {\n print \"BEGIN\\n\";\n}\nU"..., 8192) = 146 write(1, "BEGIN\n", 6) = 6 read(3, "", 8192) = 0 close(3) = 0 write(1, "UNITCHECK\n", 10) = 10 write(1, "CHECK\n", 6) = 6 write(1, "INIT\n", 5) = 5 write(1, "MAIN\n", 5) = 5
      Note that the file is closed right after BEGIN (and before UNITCHECK). So no handle to it can exist. But, if we add
      __DATA__ whatever
      that it changes a bit...
      open("t.pl", O_RDONLY) = 3 ... read(3, "BEGIN {\n print \"BEGIN\\n\";\n}\nU"..., 8192) = 165 write(1, "BEGIN\n", 6) = 6 fcntl(3, F_SETFD, FD_CLOEXEC) = 0 write(1, "UNITCHECK\n", 10) = 10 write(1, "CHECK\n", 6) = 6 write(1, "INIT\n", 5) = 5 write(1, "MAIN\n", 5) = 5 ... close(3) = 0 exit_group(0) = ?
      Now the file isn't closed until exit. So without __DATA__ there is no handle to the file, and the only handle (that I can find :) is DATA.

      Anyway, let us know if you'll find something in perl5db.pl or somewhere else.

        > Anyway, let us know if you'll find something in perl5db.pl or somewhere else.

        see http://cpansearch.perl.org/src/SHAY/perl-5.22.1/lib/perl5db.pl

        line 405

        =head4 C<@dbline> Local alias to the magical line array, C<@{$main::{'_<'.$filename}}> , supplied by the Perl interpreter to the debugger. Contains the source.

        and line 176

        =head1 DATA STRUCTURES MAINTAINED BY CORE There are a number of special data structures provided to the debugger + by the Perl interpreter. The array C<@{$main::{'_<'.$filename}}> (aliased locally to C<@dbline> via glob assignment) contains the text from C<$filename>, with each element corresponding to a single line of C<$filename>.

        Seems to be magic. Dunno if it depends on debug flags or just the context of the DB package like other magic (e.g. @DB::args )

        Anyway, let us know if you'll find something details about that magic. ;-).

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

        To clarify, the source filter thing should work, and maybe there is a way to make the file to stick around after BEGIN (without __DATA__), but in my opinion that's a bit too obscure and I don't see anything particularly complex or performance-intensive in just opening it again... but YMMV.