Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re^2: Introspecting the current Perl file via DATA, even w/o DATA?

by LanX (Sage)
on Feb 05, 2016 at 01:13 UTC ( #1154458=note: print w/replies, xml ) Need Help??


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

> 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!

  • Comment on Re^2: Introspecting the current Perl file via DATA, even w/o DATA?
  • Download Code

Replies are listed 'Best First'.
Re^3: Introsepcting the current Perl file via DATA, even w/o DATA?
by Anonymous Monk on Feb 05, 2016 at 01:50 UTC
    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!

        Anyway, let us know if you'll find something details about that magic. ;-)
        You're so lazy, LanX ;) I'm sure you could do it yourself, but if you insist...
        # main.pl BEGIN { $^P = 0x400; } use test ();
        and
        # test.pm my @source = @{ $main::{ '_<' . __FILE__ } }; print for @source; 1;
        Now, the thing is, you have to set $^P before the file (test.pm in this case) is even opened. So you can't do it inside test.pm itself, I don't think...

        Is that good enough for you?

      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.
        I think it's the only way, and a quick open if done at the right time, won't penalize the objective.

        Update: What you've shown here is very intriguing. Why are you Anonymonk?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1154458]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2022-05-16 09:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (62 votes). Check out past polls.

    Notices?