Hi,
I just found out that the implementation of POE uses constant functions a
lot. Hey, that's an exceptional quality! There is an experimental module
called Package::Transporter, which aids in managing constant functions.
Comparison between existing definitions, taken from lib/POE/NFA.pm:
sub SELF_RUNSTATE () { 0 }
sub SELF_OPTIONS () { 1 }
sub SELF_STATES () { 2 }
sub SELF_CURRENT () { 3 }
sub SELF_STATE_STACK () { 4 }
sub SELF_INTERNALS () { 5 }
sub SELF_CURRENT_NAME () { 6 }
sub SELF_IS_IN_INTERNAL () { 7 }
And the definition with Package::Transporter:
use Package::Transporter sub{eval shift}, sub {
$_[0]->array_indices('SELF_', [],
qw(RUNSTATE OPTIONS STATES CURRENT STATE_STACK
INTERNALS CURRENT_NAME IS_IN_INTERNAL));
};
The convenience function array_indices automates the enumeration, which is
a subtle feature: by using constant functions for array
indices or hash keys, the source for structural errors can be moved
into one place (where the functions are defined). That is definitely an
improvement. But only automation actually eliminates the source, which can
be seen as the motivation behind Package::Transporter.
Implicit sharing of constant functions (and other definitions like
automatically generated accessors) across packages is also supported by
Package::Transporter. Either along the package hierarchy (stop at every ::
and look if there are public definitions) or along the package names in
@ISA. The latter practically means that inheritance is available for
methods as well as attributes, even if the object is an array reference.
I'm not implying to migrate POE to Package::Transporter. Again, it's
experimental and by default refuses to install from the CPAN shell for
that reason. But the first lines of POE modules look very much like my
modules did before Package::Transporter. So I thought it would be of
general interest to you.
Thanks for POE and keep up the excellent work.
-Winfried