Beat: uff uff! our our gib uns heute...

Beitrag lesen

na dann machen wir mal weiter...
Wenn ich dich jetzt richtig verstanden habe, hast du ein Hauptmodul, dass Perl Module nachlädt, die Text verarbeiten/parsen sollen. Dieser enthält Funktionen und Attribute, ist also am Schluss ein Objekt.

Fast. Der letzte teil ist nicht korrekt.
Die importierten Funktionen sind keine Objekte.

Objekte sind Instanzen von verschiendenen im hauptscript erzeugten Objekte.
Jede Instanz hat seine eigene Initialisierung, seinen eigenen Datenzustand, und seine eigene importierte PC-Funktionen.

Allerdings denke ich, dass die Arbeit mit mehreren Objekten eher die Ausnahme ist.

Wenn die Module Zugriff auf die Instanz des Hauptmoduls haben sollen, solltest du diese z.b. dem Konstruktor übergeben oder an der Stelle wo der Text geparst wird.

Und um ein bisschen konkret zu werden.
Ich hab an deinem Konzept nicht verstanden, was mit den geparsten Modulen passieren soll.
Du hast einmal die Texte und Module mit einem Hash %ex, aber was soll dann mit $PC passieren? Soll $PC erweitert werden? Mit einem Namensraum oder mit Funktionen?
Und wenn mit Funktionen, heißt das, das immer nur ein Modul geparst werden kann? Oder mehrere die sich eventuell gegenseitig überschreiben?

Und, bist du sicher, das dein Ansatz ein Vorteil gegenüber einem gängigen Templatesystem ist?

Ich bin mir leider, was OOP in perl betrifft, in gar nichts sicher.
Ich weiss, dass our kein geeigneter Weg ist, wenn man Daten privat halten will. Aber dann ist OOP in perl überhaupt kein guter Ansatz.

Wichtiger als die privatisierung ist die einheitliche öffentliche Schnittstelle, und diese soll dann unabhängig von der inneren Struktur sein.
Das ist mein Ziel.

  
use PC::Parser # es wird new() exportiert  
my $ob->PC::Parser new(); # typisch ausgeführt mit:  
  
#...  
#im Modul  
  
sub new { # classref,  
   my $class = shift;  
   my $self = {  
      option => {},  
      storage => {},  
      default => {},  
      'system' => {  
          stripslashatend => 1,  
          error => '',  
      },  
   };  
   bless $self, $class;  
   $c_self = $self;  
   $self->__initialize();  
   return $self;  
}  

Es ist einfach so, dass jede sub, der ich ein $self übergebe
automatisch öffentlich wird für das Hauptscript.

$self->__initialize(); #kopiert ein hashtmplate mit
                           corefunktionen in die Instanz

Nun Hauptscript ist die primäre Anwenderschicht des Moduls.
Die sekundäre wird dann die Nutzung des hauptscripts sein.
Die sekundäre Schicht schreibt puren Text mit pc Codes. Da ist
kein Problem.

Nun habe ich einige methoden
sub init
sub initfile
sub parse

Die öffentlich sind. Sie tauschen das Self aus

Dann habe ich aber einen ganzen Stapel von nicht öffentlichen Funktionen
und von core oder modul pc-funktionen.
Da will ich nicht jedesmal $self übergeben.
Statt dessen überlege ich mir:
Zwischen Aufrufen der öffentlichen Methoden bleibt die bearbeitete
Instanz konstant.
Deshalb kopiere ich in new() das $self in $c_self, das mit my privat ist.
Es kann also nur innerhalb des eigenen Moduls verwendet werden.

nun ist also $c_self ein alias zum gegenwärtigen $self
ich kann also in meinen vielen privaten Funktionen $c_self->{option} etc abfragen und setzen. Aber es bleibt privat.

Aber ich brauche etwas um Daten zu holen für Funktionen, die in einem anderen package oder file kompiliert werden. Hier kommt die Funktion:

  
our $PC = sub{  
   if( $_[0] ){  
      if( $_[0] eq 'option'){  
          ( exists $c_self->{option}   and  
            exists $c_self->{option}{ $_[1] } )  
           ? return $c_self->{ option }{ $_[1] }  
           : return '';  
      }  
      if( $_[0] eq 'default'){  
         ( exists $c_self->{default}{ $_[1] } and  
           exists $c_self->{default}{ $_[1] }{ $_[2] } )  
          ? return $c_self->{ default }{ $_[1] }{ $_[2] }  
          : return '';  
      }  
    }  
    else{ return $c_self; }   # DIESE ZEILE kann ich auch unterlassen.  
};  

$PC->() gibt also das $self zurück
$PC->() ist ein getter für die Daten in $self->{}

Diese Subref stelle ich nun in den Untermodulen zur Verfügung.

Das sieht dann in meinem konkreten Test-Untermodul  so aus:

  
our $PC;  
our %export = (  
   title => {  
      function => sub {  
         ${$_[0]} = '<';  
         ${$_[0]} .= $PC->('option', 'element') || $PC->('default', 'title', 'element');  
         $PC->('option', 'class') || $PC->('default', 'title', 'class')  
              and ${$_[0]} .= ' class="' . $PC->('option', 'class') || $PC->('default', 'title', 'class') . '"';  
         ${$_[0]} .= '>'. parser( $PC->('option', 'c') ) .'</';  
         ${$_[0]} .= $PC->('option', 'element') || $PC->('default', 'title', 'element');  
        ${$_[0]} .= '>';  
      },  
      default => { element => 'h2', class => 'title', },  
   },  
);  

Ich muss jetzt nur noch dokumentieren:
Es gibt eine $Scalarref, welche den hganzen Content übergibt.
Wurde eine Funktion als Listenfunktion notiert.
Beispiel
    [somlistf+[option=value][otheroption=value]]
Dann kann auf die immer zur Verfügung gestellten gegenwärtigen Optionen zugegriffen werden, über $PC->('option', 'whichoption').
Ditto kann ich defaultwerte welche die Funktion selbst definiert
gegen lokale Überschreibungen vergleichen
$PC->('default', 'thisfunkton', 'defaultoption' )

Das macht die Dokumentation klar.

Ich will nicht dass Autoren von PC--perlfunktionssammlunen direkt auf
$self->{} zugreifen können. Ebenso will ich nicht, dass ich meine innere Datenstruktur von ihnen abhängig mache.

Das ist die Rolle von $PC->().

Wie gesagt, ich möchte das der Selfcommunity zur Kritik noch alles vorlegen.
Dann will ich aber auch Testcases und alles mitliefern.
Ich muss ja auch dokumentieren, was [p:c] ist, warum [p+c], [p:c] und [p=c] vorkommen.

mfg Beat

--

><o(((°>           ><o(((°>
   <°)))o><                     ><o(((°>o