The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Quiq::TreeFormatter - Erzeugung von Baumdarstellungen

BASE CLASS

Quiq::Hash

SYNOPSIS

Der Code

use Quiq::TreeFormatter;

my $t = Quiq::TreeFormatter->new([
    [0,'A'],
    [1,'B'],
    [2,'C'],
    [3,'D'],
    [2,'E'],
    [2,'F'],
    [3,'G'],
    [4,'H'],
    [1,'I'],
    [1,'J'],
    [2,'K'],
    [2,'L'],
    [1,'M'],
    [2,'N'],
]);

print $t->asText;

produziert

A
|
+--B
|  |
|  +--C
|  |  |
|  |  +--D
|  |
|  +--E
|  |
|  +--F
|     |
|     +--G
|        |
|        +--H
|
+--I
|
+--J
|  |
|  +--K
|  |
|  +--L
|
+--M
   |
   +--N

DESCRIPTION

Ein Objekt der Klasse repräsentiert einen Baum, der mit Methoden der Klasse dargestellt (visualisiert) werden kann. Die Baumstruktur wird als eine Liste von (minestens zweielementigen) Tupeln [$level,$node,...] an den Konstruktor übergeben. Ein Tupel besteht aus der Angabe der Ebene des Knotens, des Knotens selbst und optional weiteren - frei definierbaren - Informationen, z.B. ob der Subbaum des Knotens ausgeblendet wurde. Die zusätzliche Information kann in der getText-Callback-Methode genutzt werden, um den betreffenden Knoten besonders darzustellen. Der Knoten $node kann ein Objekt oder ein Text sein. Die Ebene $level ist eine natürliche Zahl im Wertebereich von 0 (Wurzelknoten) bis n. Die Paar-Liste kann aus irgendeiner Baumstruktur mit einer rekursiven Funktion erzeugt werden (siehe Abschnitt EXAMPLE).

EXAMPLE

Baumknoten als Texte

Siehe SYNOPSIS.

Rekursive Methode mit Stop-Kennzeichen

Die folgende Methode erkennt, wenn ein Knoten wiederholt auftritt, kennzeichnet diesen mit einem Stop-Kennzeichen und steigt dann nicht in den Subbaum ab. Dies verhindert redundante Baumteile und u.U. eine Endlos-Rekursion (wenn die Wiederholung auf einem Pfad vorkommt).

sub hierarchy {
    my $self = shift;
    my $stopH = shift || {};

    my $stop = $stopH->{$self}++;
    if (!$stop) {
        my @arr;
        for my $node ($self->subNodes) {
            push @arr,map {$_->[0]++; $_} $node->hierarchy($stopH);
        }
    }
    unshift @arr,[0,$self,$stop];

    return wantarray? @arr: \@arr;
}

Baumknoten als Objekte

Hier ein Beispiel für eine rekursive Methode einer Anwendung, die eine Klassenhierarchie für eine bestimmte Klasse ($self) ermittelt. Die Methode liefert die Klassenhierarchie als Paar-Liste für Quiq::TreeFormatter:

sub classHierarchy {
    my $self = shift;

    my @arr;
    for my $cls ($self->subClasses) {
        push @arr,map {$_->[0]++; $_} $cls->classHierarchy;
    }
    unshift @arr,[0,$self];

    return wantarray? @arr: \@arr;
}

Hier sind die Knoten $node Objekte, deren Text für die Darstellung im Baum durch eine anonyme Subroutine produziert wird. Die Subroutine wird mittels der Option -getText an $t->asText() übergeben:

my $cls = $cop->findEntity('Quiq/ContentProcessor/Type');
my $arrA = $cls->classHierarchy;
print Quiq::TreeFormatter->new($arrA)->asText(
    -getText => sub {
        my ($cls,$level,$stop) = @_;

        my $str = $cls->name."\n";
        for my $grp ($cls->groups) {
            $str .= sprintf ": %s\n",$grp->title;
            for my $mth ($grp->methods) {
                $str .= sprintf ":   %s()\n",$mth->name;
            }
        }

        return $str;
    },
);

Ein Ausschnitt aus der produzierten Ausgabe:

+--Quiq/ContentProcessor/Type
   : Erzeugung
   :   create()
   : Objektmethoden
   :   entityFile()
   :   entityId()
   :   entityType()
   :   files()
   :   fileSource()
   :   fileSourceRef()
   :   appendFileSource()
   :   name()
   :   pureCode()
   : Intern
   :   needsTest()
   :   needsUpdate()
   |
   +--Jaz/Type
      |
      +--Jaz/Type/Export
      |  : Erzeugung
      |  :   create()
      |  : Entitäten
      |  :   entities()
      |  : Reguläre Ausdrücke
      |  :   excludeRegex()
      |  :   selectRegexes()
      |  : Verzeichnisse
      |  :   adminDirectories()
      |  :   rootDirectory()
      |  : Verzeichnisse
      |  :   subDirectories()
      |  : Export
      |  :   rewriteRules()
      |  :   export()
      |
      +--Jaz/Type/Language
      |
      +--Jaz/Type/Library
      |
      +--Jaz/Type/Package
      |  : Erzeugung
      |  :   create()
      |  : Eigenschaften
      |  :   level()
      |  :   levelName()
      |  : Entitäten
      |  :   entities()
      |  :   hierarchy()
      |  :   package()
      |  :   subPackages()
      |  : Reguläre Ausdrücke
      |  :   regexes()
      |
      ...

METHODS

Konstruktor

new() - Instantiiere Baum-Objekt

Synopsis

$t = $class->new(\@tuples);

Arguments

@tuples

Liste von Tupeln [$level, $node, ...]. Die Komponenten ... werden transparent weitergereicht.

Returns

Referenz auf Baum-Objekt.

Description

Instantiiere ein Baum-Objekt und liefere eine Referenz auf dieses Objekt zurück.

Darstellung

asText() - Erzeuge Text-Repräsentation des Baums

Synopsis

$str = $t->asText(@opt);

Options

-format => 'debug'|'compact'|'tree' (Default: 'tree')

Format der Ausgabe (s.u.)

-getText => sub { my ($node,@args) = @_; ... return $text }

Callback-Funktion zum Ermitteln des Textes des Knotens. Der Text kann mehrzeilig sein.

Returns

Baumdarstellung (String)

Description

Erzeuge eine Text-Repräsentation des Baums und liefere diese zurück.

debug

0 0 A
1 1   B
1 2     C
0 3       D
1 2     E
0 2     F
0 3       G
0 4         H
1 1   I
1 1   J
1 2     K
0 2     L
0 1   M
0 2     N

compact

A
  B
    C
      D
    E
    F
      G
        H
  I
  J
    K
    L
  M
    N

tree

A
|
+--B
|  |
|  +--C
|  |  |
|  |  +--D
|  |
|  +--E
|  |
|  +--F
|     |
|     +--G
|        |
|        +--H
|
+--I
|
+--J
|  |
|  +--K
|  |
|  +--L
|
+--M
   |
   +--N

VERSION

1.220

AUTHOR

Frank Seitz, http://fseitz.de/

COPYRIGHT

Copyright (C) 2024 Frank Seitz

LICENSE

This code is free software; you can redistribute it and/or modify it under the same terms as Perl itself.