Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Filehandle of the current sourcecode, pointing after last code line?

by LanX (Sage)
on Oct 12, 2014 at 15:39 UTC ( #1103547=perlquestion: print w/replies, xml ) Need Help??

LanX has asked for the wisdom of the Perl Monks concerning the following question:

DATA is - as some of you already know - the filehandle of the currently executed sourcecode, just pointing behind the last code-line after compilation. (see SelfLoader and perldata for details)

Question : Is there a way to get this filehandle without specifying a __DATA__ or __END__ section, i.e. without reopening $0 and always pointing behind the last codeline after compilation (even if there is already a __DATA__ section defined).

Otherwise if I have defined DATA filehandles in various packages, can I check which file (if existent) is associated with it?

Or if there is no pure Perl way to do it, is it possible to inspect this info with help of the B backend or other magic?

For motivation see Re^2: Why shows B::Deparse __END__ as __DATA__? (BUG #1) following.

Cheers Rolf

(addicted to the Perl Programming Language and ☆☆☆☆ :)

Replies are listed 'Best First'.
Re: Filehandle of the current sourcecode, pointing after last code line?
by Anonymous Monk on Oct 12, 2014 at 17:31 UTC

    Question : Is there a way to get this filehandle without specifying a __DATA__ or __END__ section, i.e. without reopening $0 and always pointing behind the last codeline after compilation (even if there is already a __DATA__ section defined)

    No, I don't think so, only stuff like open DATA, '<', \'this works too';

    Otherwise if I have defined DATA filehandles in various packages, can I check which file (if existent) is associated with it?

    No, I don't think so, you cannot get filename from filehandle, there is no api and no guarantee there exists a filename, but %INC ought to have package/filename associations ...

    Or if there is no pure Perl way to do it, is it possible to inspect this info with help of the B backend or other magic?

    I don't know but I doubt it :)

    if (tmp && tmp != KEY___DATA__ && tmp != KEY___END__

    http://perl5.git.perl.org/perl.git/blob?f=t/io/data.t

      Thanx, that's what I expected... :-/

      The only way I see to fix the bug in Deparse is to compare the possible DATA handles (which are already at the right position) with the content if $0 / __FILE__ .

      Not elegant though...

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

Re: Filehandle of the current sourcecode, pointing after last code line?
by shmem (Chancellor) on Oct 13, 2014 at 09:19 UTC

    Just fully qualify your file handles.

    # file Foo.pm package Foo; 1; __DATA__ Foo foo foo foo
    # file Bar.pm package Bar; 1; __DATA__ print Bar. I told you so.

    Last, the script...

    #!/usr/bin/perl use Foo; use Bar; print while <DATA>; print "Foo:\n"; print while <Foo::DATA>; print "Bar:\n"; print while <Bar::DATA>; __DATA__ so this works. __END__ so this works. Foo: Foo foo foo foo Bar: print Bar. I told you so.

    If you can read from the different DATA filehandles, you've got them. ;)

    Parting from there, you can get at the file name via fileno and /proc/$$/fd/ (on linux, that is):

    #!/usr/bin/perl use Foo; use Bar; print while <DATA>; system "ls -l /proc/$$/fd"; print "Foo: ",fileno Foo::DATA, "\n"; print while <Foo::DATA>; print "Bar: ",fileno Bar::DATA, "\n"; print while <Bar::DATA>; __DATA__ so this works.
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      Did you read the "motivation" part? :)

      update
      I.e. I have no control about the inspected code and it has to be cross platform...

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

        Did you read the "motivation" part? :)

        Yes, I did. And I can't see any bug there regarding DATA. Maybe I don't get the point.

        package Quux; our $foo = "blorflydick"; print "in Quux\n"; print while <DATA>; print $foo,$/; 1; package blorflydick; print $foo,$/; __DATA__ blorf, blorf.
        #!/usr/bin/perl use Foo; use Bar; use Quux; print while <DATA>; print "Foo (",fileno Foo::DATA, ")\n"; print while <Foo::DATA>; print "Bar (",fileno Bar::DATA, ")\n"; print while <Bar::DATA>; print "Symbol table Quux::\n"; print "$_ => $Quux::{$_}\n" for sort keys %Quux; print "Symbol table blorflydick::\n"; print "$_ => $blorflydick::{$_}\n" for sort keys %blorflydick::; print "Quux (",fileno Quux::DATA, ")\n"; print while <Quux::DATA>; print "ok, trying blorflydick\n"; print "blorflydick (",fileno blorflydick::DATA, ")\n"; print while <blorflydick::DATA>; package Baz; __DATA__ so this works. __END__ in Quux blorflydick blorflydick Foo (4) Foo foo foo foo Bar (5) print Bar. I told you so. Symbol table Quux:: Symbol table blorflydick:: DATA => *blorflydick::DATA Quux () ok, trying blorflydick blorflydick (6) blorf, blorf.

        I think of the DATA filehandle as an alias to the fully qualified DATA filehandle with similar semantics as our, with the difference that it isn't file scoped like our variables are.

        So, the blorflydick::DATA filehandle points to Quux.pm which is not a bug IMHO.

        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1103547]
Approved by Perlbotics
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2022-10-07 23:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My preferred way to holiday/vacation is:











    Results (30 votes). Check out past polls.

    Notices?