This is an archived low-energy page for bots and other anonmyous visitors.
Please sign up if you are a human and want to interact.
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Hi Monks,
I would like to know is there a way you can use several
__DATA__ & __END__ at the same file .
Let's say I want to print these sections , which __DATA__ will I'll refer to ? The next one ? The first one ? I think I'll be able to do it if I'll declare several pacakges in the same file and each package will include only one print function and one __DATA__ section.
What do you think guys ?
Thx
michaelg
Re: multiple __DATA__ && __END__
by gjb (Vicar) on Nov 20, 2003 at 08:51 UTC
|
| [reply] |
Re: multiple __DATA__ && __END__
by jeffa (Bishop) on Nov 20, 2003 at 09:04 UTC
|
Hello michaelg, did you forget to log in before you
posted? If so, maybe now is the time to change your default
theme to something that looks different, like i do (i use
the Dark Theme). Also, you (and anyone else who reads this
who is "guilty" of such)
should stop using so many <br> tags. I used to be the
same way until someone made me realize that this is a
complete waste of your time. Remember, folks use different
screen resolutions and application sizes ... when you use
<br> tags to make line breaks, you are assuming that the
folks who read your post are using the same resolution and
application size as you. We don't! So please, stop using
<br> tags to make line breaks: let the browser make the desicion,
unless you prefer
to write your posts like haikus
please use the <p> tag
;)
Now then, as for the question ... do as gjb says and look
into Inline::Files. It's very easy to grasp, but
i wonder if you are missing a better, more maintable
solution? Why do you need two DATA sections in one file?
I like to use Inline::Files for quick and dirty tests or
examples that i post here at the Monastery, but i never use
it in production. Sometimes doing it the "old way" is
better - in this case, just store them as text files and
open them up.
UPDATE:
I guess i'll have to explicitly add that when i say use
<p> tags instead of <br/> tags ... i don't mean
replace all of the <br/> tags in you post with
<p> tags! I mean write a full paragraph and
enclose that paragraph in a <p></p> tag pair.
And for the record, i write one sentance paragraphs when
they are appropriate. ;)
| [reply] |
|
|
hi jeffa
Thanks for your answer, well I have 2 problems I work for a company with only so little respect to perl that meens that most of CPAN modules arn't installed here include inline. The second problem is that the app I'm writing should be deliver to customers as one binary file with no installation tree what so ever , just download it and use it. so I don't have any file that I can open, so I keep all my text in a .pm __DATA__ segment .
well now I need to write help for the app and I 8 the thought that I have to create about 10 packages for that.
So do you have something else in mind? :)
Michael
no theam yet ,SIR !!
| [reply] |
|
|
Ah. Without using modules you are restricted to a single __DATA__ per source file. You could store a Storable serialized object there though and that would give you arbitrary complexity. Storable is in the core perl distribution so your customers should have it. Or... if you need to package up a binary you should check out PAR to create the executable. Just keep in mind that you can't prevent (ever) your customers from being able to read your code.
| [reply] |
Re: multiple __DATA__ && __END__
by synistar (Pilgrim) on Nov 20, 2003 at 10:16 UTC
|
gjb's suggestion is probably what you want. But another approach you could try is storing a serialized data structure in the __DATA__ segment (for example using Data::Dumper or FreezeThaw). This allows you to store whatever you want and spares you the effort of parsing it too.
| [reply] |
Re: multiple __DATA__ && __END__
by Anonymous Monk on Nov 20, 2003 at 16:53 UTC
|
I was unaware of the nifty modules mentioned. Up until now I have tended use prefixes to distinguish multiple categories of data in the __DATA__ section. If for aesthetic reasons you want to stick a __DATA__ section before __END__ (after which you could, e.g., have your POD), just stop reading from DATA when you see /^__END__$/.
E.g.:
use strict;
use warnings;
while (<DATA>) {
chomp;
last if /^__END__$/; # stop when __END__ is encountered
next if /^\s*(#.*|\s*)$/; # skip blank lines or comment lines
# Clip out and remove category prefix ("word" characters terminated by a colon)
if (s/^(\w+)://) {
my $category = $1;
# P.S. It's not really necessary to copy $1, but good if you are going to be
# fooling with other regex stuff.
print "$_ is in the $category category\n";
} else {
die "unexpected input in __DATA__ section: '$_'";
}
}
exit 0;
__DATA__
# 3 categories: animal, vegetable, and mineral
ANIMAL:dog
ANIMAL:cat
VEGETABLE:apple
VEGETABLE:mushroom, the State Vegetable of Pennsylvania,
MINERAL:granite
__END__
=pod
hoo hah
=cut
| [reply] |
Re: multiple __DATA__ && __END__
by Coruscate (Sexton) on Nov 20, 2003 at 18:27 UTC
|
Whenever this question comes up, the first solution mentioned is always "use Inline::Files". While the module does do what is asked, I find that the module lacks a little. I've looked at the source and decided my perl foo is not strong enough to make the changes I'd like to see introduced.
The problem is the simple fact that if you use Inline::Files, you cannot use the 3-arg form of open(). It's as simple as that. The following program will not function as expected, because Inline::Files overrides perl's open(). So all Inline::Files sees is open my $fh, '>';, which opens an *ANON filehandle at the end of your file (so the contents of *FOO and *BAR are appended to your file, rather than to 'foo.txt'. The non-working example:
#!c:/perl/bin/perl -w
$|++;
use strict;
use Inline::Files;
open my $fh, '>', 'foo.txt' or die "open failed: $!";
print $fh do { local $/; (<FOO>, <BAR>) };
close $fh;
__FOO__
foo here
__BAR__
bar here
There is one solution to this. Whenever I wish to open a _real_ file (such as 'foo.txt'), I can call 'CORE::open()', rather than 'open()'. I just choose not to do so, because I don't like it :)
This little snippet is located in my junk drawer. I've never really used it, I discovered the wonderful world of templates shortly after I threw it together. But it works. It doesn't do the extensive cool stuff that Inline::Files does (such as opening these data sections for writing), but it gets the job of reading them done :)
#!c:/perl/bin/perl -w
$|++;
use strict;
CHECK {
no strict 'refs';
my %fh = (
do { local $/; <DATA> } =~
m#^__(.+?)__\n(.*?)\n?(?=\n?__|\z)#msg
);
open *{$_}, '<', \$fh{$_}
or die "inline open failed: $!" for keys %fh;
}
use vars qw(*FOO *BAR);
open my $fh, '>', 'foo.txt' or die "open failed: $!";
print $fh do { local $/; (<FOO>, <BAR>) };
close $fh;
__DATA__
__FOO__
foo here
__BAR__
bar here
| [reply] [d/l] [select] |
Re: multiple __DATA__ && __END__
by davido (Cardinal) on Nov 20, 2003 at 18:54 UTC
|
tell and seek may be used to jump around in the single __DATA__ section, allowing pretty flexible access. But let me mention something else.
I know this isn't exactly what you're asking. But there are instances where it might be just as appropriate, and somewhat simpler to use one or more HERE documents instead of the <DATA> filehandle. ...just a thought... there's always more than one way to do it. ;) A HERE doc will be equivilant to slurping an entire file into a scalar. But maybe that's not so bad in some situations. And with multiple HERE docs, the possibilities open up.
Dave
"If I had my life to live over again, I'd be a plumber." -- Albert Einstein
| [reply] |
|
|
tell and seek may be used to jump around in the single __DATA__ section.
Quite true. I'm just going to throw in the mention that tell() really is needed if you are planning to seek() your way through *DATA. Simply because *DATA is an extension of your file, so seek DATA, 0, 0; brings you to the start of the file, rather than the start of the __DATA__ section. (P.S.: I gather that you already knew this, as per your mention of tell(). Just wanted to throw in the extra info for anyone who stumbles across this and wonders how to do such a thing).
#!c:/perl/bin/perl -w
$|++;
use strict;
# incorrect - maybe not what you expect
print scalar <DATA>;
seek DATA, 0, 0; # seeks to first line of file!
print scalar <DATA>;
__DATA__
foo
bar
#!c:/perl/bin/perl -w
$|++;
use strict;
# correct
my $start = tell DATA; # tells us where __DATA__ begins
print scalar <DATA>;
seek DATA, $start, 0; # seek to the saved point
print scalar <DATA>;
__DATA__
foo
bar
| [reply] [d/l] [select] |
Re: multiple __DATA__ && __END__
by Anonymous Monk on Nov 21, 2003 at 05:03 UTC
|
#!C:/activeperl/bin/perl-w
use strict;
open(OFILE,">myfile.pm") or die("Can't open myfile.pm\n$!");
print OFILE <<EOF;
package myTestPackage;
sub mytest() { print "hello World!\n"; }
1
EOF
close(OFILE);
require "myfile.pm";
myTestPackage::mytest();
Horrible solution but this simple code works. Don't see why you can't put the Inline::Files code in the here document...
- Mark | [reply] [d/l] |
|
|