OK, to try and cut through some of the FileHandle arguments, here is a
simple FileHandle module that I just wrote up. Extract to simpleFH.pm, and
try some code like this:
use simpleFH;
$f = new FileHandle;
$f->open(">foo");
print $f->opened(),"\n";
print $f "Hello, world!";
close($f);
I've had some specific goals in mind for this code: it is to be as simple
as possible, use as _little_ of the current POSIX/FileHandle mess as
possible, and be useful as an extensible starting point. Chip, I apologize
for not basing this on your patches, but I wanted to start with a
completely clean slate.
Folks, please take a look through the code below, and shout if you think
you couldn't live with it, or if things could be done better. (Please
excuse the missing seek(), tell(), incomplete open(), etc.)
---------------- simpleFH.pm ------------
package simpleFH;
sub import {};
package FileHandle;
# Symbolic utilities
$gensym = "SYM000";
sub gensym {
*{"FileHandle::" . $gensym++};
}
sub ungensym {
local($x) = shift;
$x =~ s/.*:://;
delete $FileHandle::{$x};
}
# Constructors/destructors
sub new {
my($type,@args) = @_;
local($glob) = gensym();
my($fh) = bless \$glob, $type;
local(*hash) = *$fh;
if(@args) {
$fh->open(@args);
}
return $fh;
}
sub DESTROY {
my($self) = @_;
local(*hash) = *$self;
$self->close() if $self->opened();
}
# Status members
sub opened {
my($self) = @_;
return 0+defined fileno $self;
}
sub filename {
my($self) = @_;
local(*hash) = *$self;
return $hash{filename};
}
sub mode {
my($self) = @_;
local(*hash) = *$self;
return $hash{mode};
}
sub deleteonclose {
my($self,@new) = @_;
local(*hash) = *$self;
my($result) = 0+ $hash{DeleteOnClose};
$hash{DeleteOnClose} = $new[0] if @new;
return $result;
}
# FileHandle operations
sub open {
my($self,@args) = @_;
local(*hash) = *$self;
if(@args == 1) {
my($n) = $args[0];
$n =~ s/^\+?(<|>|>>)//;
my($m) = $args[0];
$m = "write" if $m =~ /^>/;
$m = "read" if $m =~ /^</;
$m = "append" if $m =~ /^>>/;
$m = "update" if $m =~ /^\+>/;
$hash{filename} = $n;
$hash{mode} = $m;
return open($self,$args[0]);
} else {
die "Unknown calling style of FileHandle::Open";
}
}
sub close {
my($self) = @_;
local(*hash) = *$self;
close($self);
if( $hash{DeleteOnClose} ) {
unlink($hash{filename});
$hash{DeleteOnClose} = 0;
}
}
sub read {
my($self,$len) = @_;
my($result);
read($self,$result,$len) or return undef;
return $result;
}
sub print {
my($self,@args) = @_;
return (print $self @args);
}
sub socket {
my($self,@args) = @_;
return (socket($self,@args));
}
package File::Temporary;
$path = "/tmp/";
@ISA = qw(FileHandle);
sub new {
my($type) = @_;
my($self) = FileHandle::new($type);
local(*hash) = *$self;
my($file) = $path . $$ . "000";
do {
$file++ while -e $file;
# This is a kludge, and needs to be changed to proper atomic file
# creation
} while -e $file;
$self->open("+>$file");
$hash{DeleteOnClose} = 1;
return $self;
}
1;
--
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)
simple FileHandle module that I just wrote up. Extract to simpleFH.pm, and
try some code like this:
use simpleFH;
$f = new FileHandle;
$f->open(">foo");
print $f->opened(),"\n";
print $f "Hello, world!";
close($f);
I've had some specific goals in mind for this code: it is to be as simple
as possible, use as _little_ of the current POSIX/FileHandle mess as
possible, and be useful as an extensible starting point. Chip, I apologize
for not basing this on your patches, but I wanted to start with a
completely clean slate.
Folks, please take a look through the code below, and shout if you think
you couldn't live with it, or if things could be done better. (Please
excuse the missing seek(), tell(), incomplete open(), etc.)
---------------- simpleFH.pm ------------
package simpleFH;
sub import {};
package FileHandle;
# Symbolic utilities
$gensym = "SYM000";
sub gensym {
*{"FileHandle::" . $gensym++};
}
sub ungensym {
local($x) = shift;
$x =~ s/.*:://;
delete $FileHandle::{$x};
}
# Constructors/destructors
sub new {
my($type,@args) = @_;
local($glob) = gensym();
my($fh) = bless \$glob, $type;
local(*hash) = *$fh;
if(@args) {
$fh->open(@args);
}
return $fh;
}
sub DESTROY {
my($self) = @_;
local(*hash) = *$self;
$self->close() if $self->opened();
}
# Status members
sub opened {
my($self) = @_;
return 0+defined fileno $self;
}
sub filename {
my($self) = @_;
local(*hash) = *$self;
return $hash{filename};
}
sub mode {
my($self) = @_;
local(*hash) = *$self;
return $hash{mode};
}
sub deleteonclose {
my($self,@new) = @_;
local(*hash) = *$self;
my($result) = 0+ $hash{DeleteOnClose};
$hash{DeleteOnClose} = $new[0] if @new;
return $result;
}
# FileHandle operations
sub open {
my($self,@args) = @_;
local(*hash) = *$self;
if(@args == 1) {
my($n) = $args[0];
$n =~ s/^\+?(<|>|>>)//;
my($m) = $args[0];
$m = "write" if $m =~ /^>/;
$m = "read" if $m =~ /^</;
$m = "append" if $m =~ /^>>/;
$m = "update" if $m =~ /^\+>/;
$hash{filename} = $n;
$hash{mode} = $m;
return open($self,$args[0]);
} else {
die "Unknown calling style of FileHandle::Open";
}
}
sub close {
my($self) = @_;
local(*hash) = *$self;
close($self);
if( $hash{DeleteOnClose} ) {
unlink($hash{filename});
$hash{DeleteOnClose} = 0;
}
}
sub read {
my($self,$len) = @_;
my($result);
read($self,$result,$len) or return undef;
return $result;
}
sub print {
my($self,@args) = @_;
return (print $self @args);
}
sub socket {
my($self,@args) = @_;
return (socket($self,@args));
}
package File::Temporary;
$path = "/tmp/";
@ISA = qw(FileHandle);
sub new {
my($type) = @_;
my($self) = FileHandle::new($type);
local(*hash) = *$self;
my($file) = $path . $$ . "000";
do {
$file++ while -e $file;
# This is a kludge, and needs to be changed to proper atomic file
# creation
} while -e $file;
$self->open("+>$file");
$hash{DeleteOnClose} = 1;
return $self;
}
1;
--
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)