You seem like you're trying to re-implement a graph data structure.

In case you were not aware, I'd like to point you to the very complete
implementation of Graph on CPAN (http://search.cpan.org/perldoc?Graph).

The set_vertex_attribute() method under the heading Attributes allows
you to set arbitrary (multiple) values to each node/vertex in the graph.
If you require something advanced this value could easily be a coderef
or a Moose object in its own.

I have used it in the past, and it worked very well for my problem domain.

Just my 2 cents.

-- Robin

Amelia Ireland wrote:
> Hello Moosers,
> 
> I have a load of methods that I want to set up, and I'm sure that there
> must be an easy way to do it that I'm missing.
> 
> I've got an index object IndexObject with a set of methods that look
> like this:
> 
> statements
> add_statements
> remove_statements
> (plus a load more other methods)
> 
> I have a graph object with several of these IndexObjects attached to it
> in the form of a hash, with the index name as the key and the
> IndexObject as the value. In the attributes of the graph object, I have
> 
> has 'index_h' => (is=>'rw', isa=>'HashRef[IndexObject]');
> 
> and the graph looks like this:
> 
> graph => { 'all' => IndexObject, 'links' => IndexObject, 'edges' =>
> IndexObject, (etc.) }
> 
> The various IndexObjects are accessed using the method
> $graph->get_index_by_name($name)
> 
> I want to create a set of methods like this:
> 
> links
> add_links
> remove_links
> edges
> add_edges
> remove_edges
> 
> such that (e.g.) $graph->add_links will perform 'add_statements' on
> $graph->get_index_by_name('links'), or $graph->remove_edges would
> perform 'remove_statements' on $graph->get_index_by_name('edges').
> 
> I could write all of these methods out manually, i.e.
> 
> sub add_links {
>   my $self = shift;
>   my $lix = $self->get_index_by_name('links');
>   $lix->add_statements(@_)
> }
> 
> but given that I have four IndexObjects by default, and at least seven
> standard methods, it's soon going to get unwieldy.
> 
> One thing I considered was to specify that 'index_h' handle all these
> methods:
> 
> has 'index_h' => (
>     handles => {
>         links => 'statements',
>         edges => 'statements',
>         add_links => 'add_statements',
>         add_edges => 'add_statements', [etc.]
>     });
> 
> and then use a method modifier around links, edges, add_links,
> add_edges, etc., which would use Sub::Identify to get the name of the
> method, extract the index name from it, get that index, and then perform
> the method on it:
> 
> around qw(links edges add_links add_edges) => sub {
>     my $method = shift;
>     my $self = shift;
>     ## use Sub::Identify to find out what the sub is we're calling,
>     ## extract the name of the index
>     my $name = Sub::Identify::sub_name($method);
>     $name =~ s/(.+_)?//;
>     ## get the appropriate index
>     my $ix = $self->get_index_by_name($name);
>     $ix->$method(@_);
> };
> 
> This feels like a horrible hack, though. I'm sure there is an efficient
> way to do this that I'm missing... can anyone help?
> 
> Thank you!
> Amelia.
> 
> 

Reply via email to