I would suggest using meta-programming, "has" is really just a
function so you can easily do something like:
foreach my $letter (qw( a b c d e f )) {
has "statement_index_${letter}" => (
is => 'rw',
isa => "HashRef[StatementIndex::" . uc($letter) . "]",
# ...
);
}
And you can also do the same with methods like so:
foreach my $letter (qw( a b c d e f )) {
__PACKAGE__->meta->add_method("something_" . $letter => sub {
my $self = shift;
$self->_do_something_to_get_something($letter, @_);
});
}
And so on and so forth.
I will warn you that this tends to make your classes much harder to
ready and digest, so it should not be over-used.
Also, not sure if you know about Native attributes
(Moose::Meta::Attribute::Native) since you are not mentioning them
specifically, but they might be really helpful in reducing your code.
- Stevan
On Nov 25, 2009, at 6:26 PM, Amelia Ireland wrote:
Hi Moosers,
I have a load of very similar methods to implement and I'm sure that
there must be a better way to do it than I'm doing at present.
I have a Graph object to which you can attach Statement objects;
these Statements get stored in StatementIndex objects. There are a
number of different subclasses of Statement, and these can be stored
in separate named StatementIndexes. The Graph object has an
attribute 'statement_index_h', a hash with the StatementIndex names
as keys and the index objects as values, i.e.
has 'statement_index_h' => ( is=>'rw',
isa=>'HashRef[StatementIndex]', default=>{...});
The StatementIndexes can be accessed using $graph-
>get_index_by_name($name).
The StatementIndexes themselves have methods such as
'statements' (getter/setter), 'add_statement', 'remove_statement',
'clear_all_statements', and various others.
Most instantiations of the Graph object will have four specific sets
of statements to be grouped together, so these four StatementIndex
objects are created by default; other indexes can be added if
required. These four sets are used frequently enough that they have
their own methods to access them, which mirror the methods provided
by the StatementIndex object; for example, one StatementIndex is
called 'edges', and to manipulate it, you use methods such as $graph-
>edges, $graph->add_edge, $graph->clear_all_edges, etc.. Analogous
methods would be available for the three other default
StatementIndex objects.
At the moment, for a method like $graph->add_edge, the method does
$graph->get_index_by_name('edge') to get the index, followed by
$index->add_statement. I thus have a whole load of very short subs
to implement the desired methods. I'm sure there must be a better
way of doing it than this... I thought that I could do something
involving delegation, but I couldn't get my implementation to work
(not sure if that was just my code, tho). Another thought was to use
a method modifier that would parse the name of the subroutine (using
Sub::Identify), extract the name of the index to fetch, and then
call the appropriate 'xxx_statements' on the fetched index.
Can anyone suggest a good way to do this? I feel there should be an
easy way to do this kind of thing!
Thank you in advance for any help... it's much appreciated!
Amelia.