[Raleigh-talk] Messing around with symbol tables
Paul Bennett
paul.w.bennett at gmail.com
Tue Dec 1 13:53:00 PST 2009
Suppose I have a module. That module takes objects with a cmp() method
(which behaves like the cmp or <=> operators), and deals with objects in a
sort order based on the results of $object1->cmp($object2). The objects
that it deals with also have a clone() method, which creates another
object with the same contents. I do not have, nor can I have, any other
assumptions about the objects being dealt with. Of course, to add to the
fun, the sorting is done piecemeal and on-demand rather than with the
"sort" keyword, and more to the point, also by somebody else's code (whose
API requires the method be named exactly "cmp()").
Suppose I have the following utility module, which is supposed to help me
handle those objects in both forward-sorting and reverse-sorting orders.
The idea is that the "antiobject" of $foo is identical in all respects to
$foo (with a reversible transformation of the class name), except a list
of antiobjects sorts in reverse order ...
package Antiobject;
use strict;
use warnings;
use Carp qw( confess );
use Export qw( import );
use Scalar::Util qw( blessed );
our @EXPORT = qw( antiobject );
sub antiobject {
my $object = shift;
my $orig = blessed($object) or confess('Not a blessed object');
confess('Object cannot cmp()') unless UNIVERSAL::can($orig, 'cmp');
confess('Object cannot clone()') unless UNIVERSAL::can($orig, 'clone');
my $new = $orig . '::anticlass';
{
no strict qw( refs );
if (!keys %{$new.'::'}) {
%{$new.'::'} = %{$orig.'::'};
${$new.'::'}->{'cmp'} = sub { -(${$orig.'::'}->{'cmp'}->(@_))
};
}
}
return bless $object->clone() => $new;
}
1;
__END__
This is 100% untested, but I fear in advance that it may be breaking a few
laws of Perl and/or nature, or at the very least be working on a
dangerously wrong understanding of the nature and temperament of the Perl
symbol table.
I just don't have enough of the rest of the code together to be able to
write meaningful test cases for it yet -- I'm kinda writing the rest of it
on the assumption that I'll end up with *some* kind of antiobject or
similar construct that I can plug in to my algorithms as needed.
Anything I should be aware of (aside from "DON'T PLAY AROUND IN OTHER
PEOPLE'S SYMBOL TABLES, YA DUMMY!!!") before I start trying to test &
debug it?
Most importantly: is there a safer and saner way to go about this that
does not rely on foreknowledge of the callers intent or the structure of
their objects?
Thanks,
--
Paul
More information about the Raleigh-talk
mailing list