Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^3: Introsepcting the current Perl file via DATA, even w/o DATA?

by Anonymous Monk
on Feb 05, 2016 at 01:50 UTC ( #1154459=note: print w/replies, xml ) Need Help??


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

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.

Replies are listed 'Best First'.
Re^4: Introspecting the current Perl file via DATA, even w/o DATA? (perl5db.pl)
by LanX (Sage) on Feb 05, 2016 at 15:14 UTC
    > 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?

        I found this interesting so I played with it briefly...

        # main.pl my @source = @{ $main::{ '_<' . __FILE__ } }; shift @source; # get rid of sub DB::DB{}; print for @source;
        and
        PERL5DB="sub DB::DB{}" perl -d main.pl

        Output:

        my @source = @{ $main::{ '_<' . __FILE__ } }; shift @source; # get rid of sub DB::DB{}; print for @source;

        Update: I had found @{$main::{'_<'.$filename}} yesterday but didn't have time to play with it.

        Update 2: Added shift.

        > Is that good enough for you?

        yes, I knew I can count on your collaboration! ;)

        > Now, the thing is, you have to set $^P before the file (test.pm in this case) is even opened.

        I think one could trick that², the question is rather about other penalties included.

        ... let's have a look into perlvar#$^P ...

        x400 Save source code lines into @{"_<$filename"} .

        OK this doesn't look to expensive ... benchmark needed.

        (too busy now ;-)

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

        footnotes

        ²) for instance IIRC it's possible to configure global setting for your perl interpreter.

Re^4: Introsepcting the current Perl file via DATA, even w/o DATA?
by Anonymous Monk on Feb 05, 2016 at 02:28 UTC
    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?

        Why are you Anonymonk?
        Well, considering that this is the only forum that I post on... I guess if I had to register, I wouldn't bother...

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (2)
As of 2022-05-22 11:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (80 votes). Check out past polls.

    Notices?