http://www.perlmonks.org?node_id=573856


in reply to Re: design suggestions for object integration wanted
in thread design suggestions for object integration wanted

Yes, we have been thinking about that. Actually, we envision a larger 'character data and tree(s)' object ("CDAT"). The idea is that the CDAT object has slots for trees, matrices and taxa, that each specify to the CDAT object which other objects (by UID) they're watching and what actions to take, e.g.:
my $matrix_id = $cdat->add_matrix( $matrix ); my $tree_id = $cdat->add_tree( $tree ); $cdat->add_handler( 'listener' => $tree_id, 'observable' => $matrix_id, 'handler' => \&handler, ); sub handler { my ( $listener, $observable, $method, @args ) = @_; # $method is called on $observable, # but supervisor $cdat creates an # indirection layer to notify listeners print "$method '@args'" # prints "set_name 'New matrix'" } $matrix->set_name( 'New matrix' );
...where the $tree, $taxon and $matrix objects have a way of notifying the $cdat object to trigger the handlers specified for their respective ids when they change state.

In the example, the $tree is watching the $matrix, and so when a method call is placed on the matrix, the tree can check what has changed and act accordingly.

I foresee problems with deep recursion when subsequent actions are triggered on the tree, which might in turn be watched by the matrix. How would you deal with that?

Replies are listed 'Best First'.
Re^3: design suggestions for object integration wanted
by GrandFather (Saint) on Sep 20, 2006 at 19:43 UTC

    I've not thought it through in detail, but I envisage a forward_message method on your CDAT object that disallows recursive calls with the same message object. Consider:

    sub forward_message { my ($self, $message) = @_; return undef if exists $self->{activeMessages}{$message->id_hash}; $self->{activeMessages}{$message->id_hash} = 1; # forward messages to all objects. Objects determine applicability delete $self->{activeMessages}{$message->{id_hash}}; return 1; }

    Note that both CDAT and the message are objects and retain state. Messages may trigger the immediate processing of more messages, but reprocessing "identical" messages is prohibited. The id_hash determines what is considered to be "identical".

    The idea of dynamic dispatch appeals to me for this application so I'd likely have a chunk of code in the target objects's message handlers that looks like:

    sub message_handler { my ($self, $message) = @_ my $handler = 'handler_' . $message->{action}; return undef if ! $self->can ($handler); return $self->$handler ($message); } sub handler_addTaxonName { my ($self, $message) = @_; my $newTaxon = $message->{newTaxon}; ... my $balance = $self->create_message ('rebalance', -taxon => $newTa +xon, ...); $self->{CDAT}->forward_message ($balance); return 1; } sub handler_rebalance { my ($self, $message) = @_; my $newTaxon = $message->{newTaxon}; ... }

    DWIM is Perl's answer to Gödel
      Thanks for these suggestions! I'm going to have to meditate on this a bit more. Sounds like a good way to avoid deep recursions.