[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

[FWP] REALLY spiffy typeglob code, but with a significant weakness



I'm working on an e-mail client written in Perl.  Each type of mail folder
supported by the program has its unique functionality encapsulated in a
class (eg: Folder::UNIX, Folder::MH).  One of the more important duties
performed by objects of these classes is to provide a way to import
messages into their respective folders.  Conceptually I would like to have
a method that returns a filehandle that an incoming message can be written
to; but because multiple messages are typically written all at once, there
needs to be some sort of trigger action taken to indicate the end of one
message and the beginning of the next.  My first attempt at resolving this
issue involved returning a member of a class that provides a stream of
filehandles via its next() method:

my $factory = $folder->import_handle;
my $handle = $factory->next;
print $handle "...message 1...";
$handle = $factory->next;
print $handle "...message 2...";

...and so on.  This works well, but I'm vaguely dissatisfied with it; it
just seems excessively wordy.

Today I had a brainstorm: using the subroutine slot of the filehandle's
typeglob as the trigger I originally wanted.  Here's an example of using
this strategy to create a special filehandle that writes to a stream of
files called "file-1", "file-2", etc.  The new file is opened when the
filehandle's subroutine slot is invoked.  The current file suffix is stored
in the typeglob's scalar slot.

----------------------------------------------------------------------
use Symbol;

sub special_handle {
	my $file = gensym;
	*$file = sub {
		my $filenum = ++${ *$file };
		open $file, ">file-$num" or die "Can't open file file-$num: $!\n";
	};
	*$file->();  # open initial file
	$file;
}

my $file = special_handle();
print $file "This goes to file-1\n";
*$file->();
print $file "This goes to file-2\n";
*$file->();
# ...
----------------------------------------------------------------------

This seems incredibly cool: the typeglob's subroutine slot is a closure
whose attached data consists of a reference to the typeglob itself!
However, I soon realized that this property also creates a memory leak;
when the typeglob reference returned by special_handle() goes out of scope,
the typeglob still hangs around because of the reference to it that still
exists in the closure.

The only way out of this that I can see is to have the closure nuke itself
when the user calls it with a special argument that indicates that it is no
longer needed.  For instance, the first line of the closure might be:

	*$file = sub { }, return if @_;

...and the code that uses the typeglob can indicate it no longer needs it
by calling:

	*$file->(1);

This is OK, I suppose, but I'd really like more IO::File-ish behavior
whereby everything is nicely cleaned up when all of the non-closure
typeglob references go out of scope.

Any ideas?

-- 
Sean McAfee | GCS d->-- s+++: a28 C++ US+++ P+++$ L++ E- W+ N++ |
            | K w--- O? M- V-- PS+ PE Y+ PGP?>++ t+() 5++ X R+  | mcafee@
            | tv+ b++ DI++ D+ G e++ h r---* y+>++               | umich.edu

==== Want to unsubscribe from Fun With Perl?  Well, if you insist...
==== Send email to <fwp-request@technofile.org> with message _body_
====   unsubscribe