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
|