Obwohl ich mit DVK zum größten Teil zustimmen, muss ich sagen, wenn Sie Eintauchen in Arrays von Arrays von Hashes starten, werden Sie einen Code Komplexitätsgrad erreicht, die schwer ohne viel Spinnen halten von Köpfe und Käfer.
An diesem Punkt würde ich wahrscheinlich nach einem Objekt und einer Klasse für ein bisschen syntaktischen Zucker greifen.
my $transitions = TransitionGraph->new();
$transition->add(1, { targets => [ 2, 5 ] });
$transition->add(2, { targets => [ 1, 5 ] });
$transition->add(2, { targets => [ 2 ], conditions => [ $some_condition ] });
$transition->add(2, { targets => [ 3, 4 ], conditions => [ $other_condition, $more_cond ]});
$transition->add(3, { targets => [4,2] });
$transition->add(4, { targets => [3,2] });
$transition->add(5, { targets => [] });
if($transition->allowed(1 , 3)){
}
Klasse Implementierung ist dem Benutzer überlassen, aber ich würde Elch verwenden.
Der Hauptvorteil davon ist, dass Sie die Funktionsweise des Zustandsdiagramms kapseln, sodass Sie es einfach verwenden können und sich darüber Gedanken machen müssen, wie das Diagramm unabhängig von seinem Verwendungszweck funktioniert.
nb. In der oben vorgeschlagenen API erstellt add() einen neuen Datensatz, falls noch keiner existiert, und aktualisiert diesen Datensatz, falls er existiert. Dies erwies sich als einfacher als "Upgrade" -Methoden oder "Holen Sie sich dieses Element und dann ändern Sie es" -Techniken.
Intern könnte es dies tun, oder so ähnlich:
sub add {
my ($self , $input_state, $rules) = @_;
my $state;
if ($self->has_state($input_state)) {
$state = $self->get_state($input_state);
} else {
$state = TransitionGraphState->new(source_id => $input_state);
$self->add_state($input_state, $state);
}
my $targets = delete $rules{targets};
for my $target (@$targets) {
$state->add_target($target, $rules);
}
return $self;
}
sub allowed {
my ($self, $from, $to) = @_;
if (not $self->has_state($from)){
croak "NO source state $from in transition graph";
}
my $state = $self->get_state($from);
return $state->allowed_to($to);
}
Dies hat auch den kühlen Perk nicht einen bestimmten Code festgelegt erfordern auf den Unterknoten zu arbeiten, können Sie separate Instanzen erstellen, mit ihr eigenes Verhalten für den Fall, dass Sie möchten, dass ein Quellzustand anders behandelt wird.
$transition->add_state(2, $some_other_class_wich_works_like_transitiongraphstate);
Ich hoffe, dies ist hilfreich =).
nr. Ich habe diesen wahnsinnigen Zwang, alles zu abstrahieren. Ich hätte eine Moose :: Role für TransitionStateGraphs, und der interne Status-Hash würde mit moose-eigenen Merkmalen gemacht werden. Obwohl ich es so sehr mag, dass der Zustand bisher noch nicht erlaubt war, musste ich noch keine Schleife machen =) –