Mailing List Archive

FileHandle patches, Part 1
This is the first part of the FileHandle patches I posted a long
time ago, in a galaxy far, far away.

New modules:

Symbol:
Encapsulates the creation of anonymous globs.
You can say "Symbol::generate" for a plain glob, or
"new Symbol" for one blessed into the "Symbol" package.

DirHandle:
All the usual object-encapsulation tricks for the directory
functions.

SelectSaver:
Creating a SelectSaver object saves the currently selected
output handle. Its destruction automatically restores the
saved handle. Thus you can avoid explicit restoration,
simplifying code, and you'll never accidentally forget it.

# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Chip Salzenberg <chip@b4pph1a6> on Thu Aug 24 13:18:12 1995
#
# This archive contains:
# lib/DirHandle.pm lib/Symbol.pm
# lib/SelectSaver.pm
#

LANG=""; export LANG
PATH=/bin:/usr/bin:$PATH; export PATH

echo x - lib/DirHandle.pm
cat >lib/DirHandle.pm <<'@EOF'
package DirHandle;

=head1 NAME

DirHandle - supply object methods for directory handles

=head1 SYNOPSIS

use DirHandle;
$d = new DirHandle ".";
while (defined($_ = $d->read)) { do_whatever($_); }
$d->rewind;
$d->close;

=head1 DESCRIPTION

The C<DirHandle> method provide an alternative interface to the
opendir(), closedir(), readdir(), and rewinddir() functions.

The only objective benefit to using C<DirHandle> is that it avoids
namespace pollution by creating globs to hold directory handles.

=cut

require 5.000;
use Symbol;
use Carp;

sub new {
croak "usage: DirHandle->new(dirname)" if @_ != 2;
my $sym = new Symbol;
opendir($sym, $_[1])
and bless \$sym;
}

sub DESTROY {
my $self = $_[0];
closedir($$self);
}

sub read {
croak "usage: DirHandle->read()" if @_ != 1;
my $self = $_[0];
readdir($$self);
}

sub rewind {
croak "usage: DirHandle->rewind()" if @_ != 1;
my $self = $_[0];
rewinddir($$self);
}

1;
@EOF

chmod 444 lib/DirHandle.pm

echo x - lib/Symbol.pm
cat >lib/Symbol.pm <<'@EOF'
package Symbol;

=head1 NAME

Symbol - create and destroy symbols for use as "anonymous" handles

=head1 SYNOPSIS

use Symbol;

# USAGE #1: BLESSED GLOB REFERENCE
$g = new Symbol;
open($g, "foo");
# ...
close($g);
undef $g;

# USAGE #2: SIMPLE GLOB REFERENCE
$g = Symbol::generate;
open($g, "foo");
print <$g>;
close($g);
undef $g;

=head1 DESCRIPTION

A C<Symbol> object is a reference to a glob that is, for all practical
purposes, anonymous. In fact it has a name, but it doesn't actually
exist in the symbol table where it was originally created, so it
cannot be accessed by name, only by reference.

If blessing the glob reference into the C<Symbol> package is not
desired -- such as for the C<FileHandle> methods in the C<POSIX>
package -- then the function C<Symbol::generate> may be used.

=cut

require 5.000;
use Carp;

sub generate;

sub new {
my $sym = generate;
print "Symbol::new ", $$sym."\n";
bless $sym;
}

sub DESTROY {
my ($sym) = @_;
print "Symbol::DESTROY ", $$sym."\n";
}

$count = 0;

sub generate {
my $name = sprintf "S%X", ++$count;
local *{$name};
\delete $Symbol::{$name};
}

1;
@EOF

chmod 444 lib/Symbol.pm

echo x - lib/SelectSaver.pm
cat >lib/SelectSaver.pm <<'@EOF'
package SelectSaver;

=head1 NAME

SelectSaver - save and restore selected file handle

=head1 SYNOPSIS

use SelectSaver;

{
my $saver = new SelectSaver(FILEHANDLE);
# FILEHANDLE is selected
}
# previous handle is selected

=head1 DESCRIPTION

A C<SelectSaver> object contains a reference to the file handle that
was selected when it was created. If its C<new> method gets an extra
parameter, then that parameter is selected; otherwise, the selected
file handle remains unchanged.

When a C<SelectSaver> is destroyed, it re-selects the file handle
that was selected when it was created.

=cut

require 5.000;
use Carp;

sub new {
croak "usage: new SelectSaver [FILEHANDLE]" unless @_ && @_ <= 2;
my $fh = select @_[1 .. $#_];
bless \$fh;
}

sub DESTROY {
my $fh = $_[0];
select $$fh;
}

1;
@EOF

chmod 444 lib/SelectSaver.pm

exit 0

--
Chip Salzenberg, aka <chs@nando.net>
"Hey, it's the Miss Alternate Universe Pageant!"
-- Crow T. Robot, MST3K: "Stranded In Space"