The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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.165

AUTHOR

Frank Seitz, http://fseitz.de/

COPYRIGHT

Copyright (C) 2019 Frank Seitz

LICENSE

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