One topic that often comes up in discussions about how to make things easier for LCFG component authors is the idea of sub-classing.
Although I had never tried it I had always assumed this was possible. Recently whilst looking through the LCFG::Component code I noticed that the list of methods are looked up in the symbol table for the module:
my $mtable = {}; for my $method ( ( keys %LCFG::Component:: ), ( eval 'keys %' . ref($self) . q{::} ) ) { if ( $method =~ m/^method_(.*)/i ) { $mtable->{ lc $1 } = $method; } } $self->{_METHOD} = lc $_METHOD; my $_FUNCTION = $mtable->{ $self->{_METHOD} };
So, this will work if your method comes from LCFG::Component
or LCFG::Component::Foo
but it wouldn’t work if you have a sub-class of Foo
. You would potentially miss out on methods which are only in Foo
(or have to copy/paste them into your sub-class).
Not only does this make sub-classing tricky it also involves a horrid string eval. There had to be a better way. Thankfully I was already aware of the Class::Inspector module which can do the necessary. This module is widely used by projects such as DBIx::Class and Catalyst so is likely to be reliable. It has a handy methods
method which does what we need:
my $_FUNCTION; my $public_methods = Class::Inspector->methods( ref($self), 'public' ); for my $method (@{$public_methods}) { if ( $method =~ m/^Method_(\Q$_METHOD\E)$/i ) { $_FUNCTION = $method; $_METHOD = $1; last; } }
Much nicer code and a tad more efficient. Now the LCFG component Perl modules are properly sub-classable.