Rob Dixon wrote:
>
> Dan Anderson wrote:
> >
> > I have a module that works with a couple of different file handles. Is
> > it possible to hide them within an anonymous hash? {} (i.e. the objects
> > data). Right now I have:
> >
> > if (condition_is_met()) {
> > open("FILE","<file");
> > }
> >
> > This is in the main body of my package (and thus, I assume, accessible
> > by all functions). Is it better to use tighter encapsulation (i.e. a
> > closure or throwing it into an anonymous hash) or just to leave it in
> > the body?
>
> I think you'd be safe like this, except that if you have a lot of them
> then you dont' know what the filehandle is going to be called. Here
> you've used *Package::FILE, but there's no general way of getting to
> that package name from any given filename. How about a hash of glob
> references?
>
> Here's a closure with a subroutine which keeps a list of handles for
> each file it has already opened. The program just uses it to print
> the next line from alternate files.
>
> I hope this helps.
>
> Rob
>
>
> use strict;
> use warnings;
>
> line_from ('filea');
> line_from ('fileb');
>
> line_from ('filea');
> line_from ('fileb');
>
> line_from ('filea');
> line_from ('fileb');
>
> {
> my %filehandle;
> my $fh;
>
> sub line_from {
>
> my $file = shift;
>
> $fh = $filehandle{$file};
>
> unless (defined $fh) {
> open $fh, $file or die $!;
> $filehandle{$file} = $fh;
> }
>
> print scalar <$fh>;
> }
> }
Nobody noticed that my 'closure' wasn't a closure! I was
going to write it that way but decided the simple subroutine
with persistent lexicals was easier and neater as it could
be self-initialising. FWIW a closure equivalent is here if
anybody's interested.
Rob
use strict;
use warnings;
my ($file1, $file2) = qw/ filea fileb /;
my %fetch = map { ($_ => file_iterator($_)) } $file1, $file2;
for my $file (($file1, $file2) x 3) {
print $fetch{$file}->();
}
sub file_iterator {
my $file = shift;
my $fh;
open $fh, $file or die $!;
sub { scalar <$fh> };
}
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]