Re: __DATA__ only one time
by broquaint (Abbot) on Nov 24, 2003 at 17:02 UTC
|
Just save the position of the __DATA__ section first time around e.g
use vars '$DATA_POS';
$DATA_POS = tell *DATA
unless defined $DATA_POS;
# update - swapped args to be in correct order
seek *DATA, $DATA_POS, 0;
while(<DATA>) { ... }
Now that will always seek to the beginning of the __DATA__ section.
| [reply] [d/l] |
Re: __DATA__ only one time
by chromatic (Archbishop) on Nov 24, 2003 at 17:46 UTC
|
I must disagree with all of the other responses so far. Why read from the pseudo-filehandle every time, since you need to muck about with seek and tell? Just read everything in once at startup:
my $data;
BEGIN
{
$data = do { local $/; <DATA> };
}
Update: Please heed tye's advice below and use this more as a guide, not as a literal code recommendation. :) | [reply] [d/l] |
|
|
Please also close DATA at the same time so that you aren't wasting one of my few available file handles by keeping one open in your module that you will never use again.
Also note that you can't access DATA inside of a BEGIN block because the compiler hasn't seen the __DATA__ token yet and so doesn't know what offset to let you start reading from and so doesn't make a DATA handle available yet.
my $data;
{
local $/;
$data = <DATA>;
close DATA;
}
You might be able to turn that block into an INIT or a CHECK block, but I've never had a need for such so I won't try to make a recommendation based on ignorance.
| [reply] [d/l] |
|
|
I was thinking this at the top of the page and by the time I scrolled down to the very bottom, I saw your node. Good thing I read that far :)
It seems like this is not only easier to code, but more efficient as well... but I have no data, so I'll shut up now.
--
Allolex
| [reply] |
Re: __DATA__ only one time
by eric256 (Parson) on Nov 24, 2003 at 17:05 UTC
|
You need to seek back to the beggining of the data section to re read it. You can use tell to find out where data begins, print it, then seek back, and print agian.
use strict;
my $start = tell(DATA);
print while (<DATA>);
seek DATA,$start,0;
print while (<DATA>);
__DATA__
Hello
| [reply] [d/l] |
Re: __DATA__ only one time
by davido (Cardinal) on Nov 24, 2003 at 17:33 UTC
|
Using seek to return to the beginning of the file for the <DATA> filehandle will do something that you may consider unexpected. It will seek to the beginning of the literal file in which the __DATA__ block exists. What I mean by that is that after seeking to the beginning of the file, the first line you read in is going to be your shebang line, the next line will be your use strict; line, and so on. You've successfully seeked to the start of your entire Perl script.
If you want to seek to the beginning of the data segment instead of the start of the script, you must first use tell to find where the data segment begins. Save the info from tell into a scalar. Then go ahead and walk through the <DATA> filehandle as desired. When you decide it's time to reset to the beginning of the __DATA__ segment, seek to the beginning of the segment by feeding seek the scalar variable that is holding onto where the segment begins, provided by that first call to tell.
Here's a snippet:
my $bof_DATA = tell DATA; # Save the location of DATA BOF.
my @slurp = <DATA>; # Read in the DATA segment.
seek DATA,$bof_DATA,0; # Return to the beginning of the
# DATA segment.
local $, = ", ";
print <DATA>, "\n"; # Run through DATA a second time.
Dave
"If I had my life to live over again, I'd be a plumber." -- Albert Einstein
| [reply] [d/l] [select] |
Re: __DATA__ only one time
by waswas-fng (Curate) on Nov 24, 2003 at 17:00 UTC
|
seek (DATA,0,0);
| [reply] [d/l] |
|
|
| [reply] |
|
|
I just thought about that and was going back to fix it, thats how long it has been since I have snuck _DATA_ sections into my code. Use B's method below as he takes into account the offset of _DATA_ for the seek.
| [reply] |
Re: __DATA__ only one time
by calin (Deacon) on Nov 24, 2003 at 18:44 UTC
|
{
local @ARGV = '/home/michaelg/helpfile';
print <>;
}
Use external DBM file (with tie/dbmopen). This way you can
easily handle more messages.
my %msgs;
dbmopen %msgs, '/home/michaelg/dbmhelp', 0600;
print $msgs{mainhelp};
# [...]
print $msgs{braindead_help};
Here-docs also come handy
print <<'FINIS';
I gave foo bars to the foo fighters , and of course Dave
well never mind ,
[...]
FINIS
| [reply] [d/l] [select] |
Re: __DATA__ only one time
by jeffa (Bishop) on Nov 24, 2003 at 20:05 UTC
|
"... then of course I don't need to read them from local files and directories."
But why is this bad? The __DATA__ section should
be used sparingly, it's really just a convient hack that
should be used for achieving quick and dirty results.
Please think twice before you use this "convenience" in
production code. Besides, i always reserve the __DATA__ (AKA __END__) section for my
POD in all production code i write.
Don't tell me that you don't document your programs. ;)
(and i don't mean # comments either)
| [reply] |