Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

Using __DATA__ from a package

by yoda54 (Monk)
on Jun 18, 2013 at 02:19 UTC ( #1039499=perlquestion: print w/replies, xml ) Need Help??
yoda54 has asked for the wisdom of the Perl Monks concerning the following question:


How would do I access local __DATA__ inside a package?


package Test; sub run { while(<Test::DATA>) { print "$_\n"; } } __DATA__ 1 #!/usr/bin/perl use strict; use warnings; use Test; Test::run();

Replies are listed 'Best First'.
Re: Using __DATA__ from a package
by Athanasius (Chancellor) on Jun 18, 2013 at 06:18 UTC

    Consider a driver script “”:

    use strict; use warnings; use MyTest; while (<DATA>) { chomp; print "MAIN: >$_<\n"; } #MyTest::run(); while (<MyTest::DATA>) { chomp; print "MAIN: >$_<\n"; } __DATA__ 32 wilma 16

    run in conjunction with a module “” (in a separate file):

    package MyTest; use strict; use warnings; sub run { while (<DATA>) { chomp; print "TEST: *$_*\n"; } close DATA; } 1; __DATA__ TEST 1 2 3


    14:19 >perl MAIN: >32 wilma 16< MAIN: >TEST 1 2 3< 16:04 >

    As can be seen, the data section in the module is accessed via __DATA__ from within the module (i.e., within package MyTest), but via MyTest::DATA from within a different package.

    But you get the same effect by uncommenting the call to MyTest::run() and using that in place of the second while loop in the driver script. Calling MyTest::run() is better practice as it maintains the encapsulation of the MyTest module.

    Note: Trying to combine the two approaches is much more difficult, as it means resetting the DATA handle in the MyTest package. So far, my experiments with open, close, and seek have been less than encouraging. But trying to read the same DATA section twice is probably a bad idea anyway.

    Update: ++poj for the link below. The solution is given in Re^2: __DATA__, seek, and tell — change sub run in “MyTest” to:

    sub run { my $datapos = tell DATA; while (<DATA>) { chomp; print "TEST: *$_*\n"; } seek DATA, $datapos, 0; }

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Also be aware that for Perl 5.12 and earlier on windows platforms the line ending characters weren't handled correctly (update: when using seek/tell on DATA). After this node a perlbug report was submitted and the problem corrected.

Re: Using __DATA__ from a package
by BrowserUk (Pope) on Jun 18, 2013 at 04:45 UTC

    I think your code might work, if there was a function call run() in the package Test. Which presumably would be wrapped around the while loop.

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Using __DATA__ from a package
by DrHyde (Prior) on Jun 18, 2013 at 11:37 UTC
    Like this:
    package Test; sub run { while(<DATA>) { print "$_\n"; } } 1; __DATA__ 1

    I made two changes to your code. First, the file handle is always DATA, not PackageName::DATA. Second, I made the package return true, so that you can use it.

    If you want to see some real-world examples, then check out these tests (and the modules under t/lib that they use) or Number::Phone::UK::Data

Re: Using __DATA__ from a package
by grondilu (Friar) on Jun 18, 2013 at 03:25 UTC

    I'm not sure, but I think DATA is not scoped to a package, but to a compilation unit (basically the file). So there is no such thing as Package::DATA.

    <DATA> would reference the same thing from any package, provided they are all in the same file.

      I'm not sure

       [perldoc://__DATA__] -> [href://|__DATA__] -> [doc://perldata]#[doc://perldata#Special-Literals] __DATA__ -> __DATA__ -> perldata#Special Literals

      Text after __DATA__ may be read via the filehandle PACKNAME::DATA , where PACKNAME is the package that was current when the __DATA__ token was encountered. The filehandle is left open pointing to the line after __DATA__. The program should close DATA when it is done reading from it. (Leaving it open leaks filehandles if the module is reloaded for any reason, so it's a safer practice to close it.) For compatibility with older scripts written before __DATA__ was introduced, __END__ behaves like __DATA__ in the top level script (but not in files loaded with require or do) and leaves the remaining contents of the file accessible via main::DATA .

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1039499]
Front-paged by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2018-03-24 01:22 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (297 votes). Check out past polls.