X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=doc%2Fhtml%2Fch04.html;h=e52c8c11d5b1a4d30331f288bd435e7ff9e83e29;hb=a23454bb1b039a31b7f77710ff663fa9152d530c;hp=2936deae8a1ef9ba89aeef87b27db3fa243d7d98;hpb=f8309cb7bc2507c19e17ec59c6c66dd7f49ea351;p=kivitendo-erp.git diff --git a/doc/html/ch04.html b/doc/html/ch04.html index 2936deae8..e52c8c11d 100644 --- a/doc/html/ch04.html +++ b/doc/html/ch04.html @@ -1,7 +1,7 @@ - - Kapitel 4. Entwicklerdokumentation

Kapitel 4. Entwicklerdokumentation

4.1. Globale Variablen

4.1.1. Wie sehen globale Variablen in Perl aus?

Globale Variablen liegen in einem speziellen namespace namens - "main", der von überall erreichbar ist. Darüber hinaus sind bareword + + Kapitel 4. Entwicklerdokumentation

Kapitel 4. Entwicklerdokumentation

4.1. Globale Variablen

4.1.1. Wie sehen globale Variablen in Perl aus?

Globale Variablen liegen in einem speziellen namespace namens + "main", der von überall erreichbar ist. Darüber hinaus sind bareword globs global und die meisten speziellen Variablen sind... speziell.

Daraus ergeben sich folgende Formen:

$main::form @@ -12,35 +12,37 @@

FILE ist global

$_ -

speziell

Im Gegensatz zu PHP™ gibt es kein - Schlüsselwort wie "global", mit dem man +

speziell

Im Gegensatz zu PHP™ gibt es kein + Schlüsselwort wie "global", mit dem man importieren kann. my, our und local machen was anderes.

my $form -

lexikalische Variable, gültig bis zum Ende des +

lexikalische Variable, gültig bis zum Ende des Scopes

our $form

$form referenziert ab hier $PACKAGE::form.

local $form -

Alle Änderungen an $form werden am Ende - des scopes zurückgesetzt

4.1.2. Warum sind globale Variablen ein Problem?

Das erste Problem ist FCGI™.

- SQL-Ledger™ hat fast alles im globalen +

Alle Änderungen an $form werden am Ende + des scopes zurückgesetzt

4.1.2. Warum sind globale Variablen ein Problem?

Das erste Problem ist FCGI™.

+ SQL-Ledger™ hat fast alles im globalen namespace abgelegt, und erwartet, dass es da auch wiederzufinden ist. - Unter FCGI™ müssen diese Sachen auch wieder - aufgeräumt werden, damit sie nicht in den nächsten Request kommen. - Einige Sachen wiederum sollen nicht gelöscht werden, wie zum Beispiel - Datenbankverbindungen, weil die ne Ewigkeit zum initialisieren + Unter FCGI™ müssen diese Sachen aber wieder + aufgeräumt werden, damit sie nicht in den nächsten Request kommen. + Einige Sachen wiederum sollen nicht gelöscht werden, wie zum Beispiel + Datenbankverbindungen, weil die sehr lange zum Initialisieren brauchen.

Das zweite Problem ist strict. Unter strict werden alle Variablen die nicht explizit mit Package, my oder our angegeben werden als Tippfehler angemarkert, - was einen vor so mancher Stunde suchen nach einem Bug erspart. Da - globale Variablen aber implizit mit Package angegeben werden, werden - die nicht geprüft, und ein Tippfehler da fällt niemandem auf.

4.1.3. Kanonische globale Variablen

Um dieses Problem im Griff zu halten gibt es einige wenige - globale Variablen, die kanonisch sind, und alles andere sollte - anderweitig umhergereicht werden.

Diese Variablen sind im Moment die folgenden neun:

  • + dies hat, seit der Einführung, u.a. schon so manche langwierige + Bug-Suche verkürzt. Da globale Variablen aber implizit mit Package + angegeben werden, werden die nicht geprüft, und somit kann sich + schnell ein Tippfehler einschleichen.

4.1.3. Kanonische globale Variablen

Um dieses Problem im Griff zu halten gibt es einige wenige + globale Variablen, die kanonisch sind, d.h. sie haben bestimmte + vorgegebenen Eigenschaften, und alles andere sollte anderweitig + umhergereicht werden.

Diese Variablen sind im Moment die folgenden neun:

  • $::form

  • %::myconfig @@ -58,43 +60,72 @@ $::dispatcher

  • $::request -

Damit diese nicht als Müllhalde misbrauch werden, im Folgenden - eine kurze Erläuterung was man von denn erwarten kann.

4.1.3.1. $::form

  • Ist ein Objekt der Klasse - "Form"

  • Wird nach jedem Request gelöscht

  • Muss auch in Tests und Konsolenscripts vorhanden - sein.

  • Enthält am Anfang eines Requests die Requestparameter vom - User

  • Kann zwar intern über Requestgrenzen ein Datenbankhandle - cachen, das wird aber momentan absichtlich zerstört

+

Damit diese nicht erneut als Müllhalde missbraucht werden, im + Folgenden eine kurze Erläuterung der bestimmten vorgegebenen + Eigenschaften (Konventionen):

4.1.3.1. $::form

  • Ist ein Objekt der Klasse + "Form"

  • Wird nach jedem Request gelöscht

  • Muss auch in Tests und Konsolenscripts vorhanden + sein.

  • Enthält am Anfang eines Requests die Requestparameter vom + User

  • Kann zwar intern über Requestgrenzen ein Datenbankhandle + cachen, das wird aber momentan absichtlich zerstört

$::form wurde unter SQL - Ledger™ als Gottobjekt für alles misbraucht. Sämtliche + Ledger™ als Gottobjekt für alles misbraucht. Sämtliche alten Funktionen unter SL/ mutieren $::form, das - heißt, alles was einem lieb ist, sollte man vor einem Aufruf von zum - Beispiel IS->retrieve_customer() in - Sicherheit bringen.

Das Objekt der Klasse Form hat leider im Moment noch viele - zentrale Funktionen Gdie vom internen Zustand abhängen, deshalb - bitte nie einfach zerstören oder überschreiben. Es geht ziemlich - sicher etwas kaputt.

+ heißt, alles was einem lieb ist (alle Variablen die einem ans Herz + gewachsen sind), sollte man vor einem Aufruf (!) von zum Beispiel + IS->retrieve_customer() in Sicherheit + bringen.

Z.B. das vom Benutzer eingestellte Zahlenformat, bevor man + Berechnung in einem bestimmten Format durchführt (SL/Form.pm Zeile + 3552, Stand version 2.7beta), um dies hinterher wieder auf den + richtigen Wert zu setzen:

  my $saved_numberformat    = $::myconfig{numberformat};
+  $::myconfig{numberformat} = $numberformat;
+  # (...) div Berechnungen
+  $::myconfig{numberformat} = $saved_numberformat;

Das Objekt der Klasse Form hat leider im Moment noch viele + zentrale Funktionen die vom internen Zustand abhängen, deshalb bitte + nie einfach zerstören oder überschreiben (zumindestens nicht kurz + vor einem Release oder in Absprache über bspw. die devel-Liste ;-). + Es geht ziemlich sicher etwas kaputt.

$::form ist gleichzeitig der Standard Scope - in den Template::Toolkit™ Templates - außerhalb der Controller: der Ausdruck [% var + in den Template::Toolkit™ Templates + außerhalb der Controller: der Ausdruck [% var %] greift auf $::form->{var} zu. Unter Controllern ist der Standard Scope anders, da lautet der Zugriff [% FORM.var %]. In Druckvorlagen sind normale Variablen ebenfall im $::form Scope, d.h. <%var%> zeigt auf - $::form->{var}. Innerhalb von Schleifen wird + $::form->{var}. Nochmal von der anderen Seite + erläutert, innerhalb von (Web-)Templates sieht man häufiger solche + Konstrukte:

[%- IF business %]
+# (... Zeig die Auswahlliste Kunden-/Lieferantentyp an)
+[%- END %]

Entweder wird hier dann $::form->{business} ausgewertet + oder aber der Funktion + $form->parse_html_template wird explizit + noch ein zusätzlicher Hash übergeben, der dann auch in den + (Web-)Templates zu Verfügung steht, bspw. so:

$form->parse_html_template("is/form_header", \%TMPL_VAR);

Innerhalb von Schleifen wird $::form->{TEMPLATE_ARRAYS}{var}[$index] - bevorzugt, wenn vorhanden.

4.1.3.2. %::myconfig

  • Das einzige Hash unter den globalen Variablen

  • Wird spätestens benötigt wenn auf die Datenbank - zugegriffen wird

  • Wird bei jedem Request neu erstellt.

  • Enthält die Userdaten des aktuellen Logins

  • Sollte nicht ohne Filterung irgendwo gedumpt werden oder + bevorzugt, wenn vorhanden. Ein Beispiel findet sich in SL/DO.pm, + welches über alle Positionen eines Lieferscheins in Schleife + läuft:

    for $i (1 .. $form->{rowcount}) {
    +  # ...
    +  push @{ $form->{TEMPLATE_ARRAYS}{runningnumber} },   $position;
    +  push @{ $form->{TEMPLATE_ARRAYS}{number} },          $form->{"partnumber_$i"};
    +  push @{ $form->{TEMPLATE_ARRAYS}{description} },     $form->{"description_$i"};
    +  # ...
    +}

4.1.3.2. %::myconfig

  • Das einzige Hash unter den globalen Variablen

  • Wird spätestens benötigt wenn auf die Datenbank + zugegriffen wird

  • Wird bei jedem Request neu erstellt.

  • Enthält die Userdaten des aktuellen Logins

  • Sollte nicht ohne Filterung irgendwo gedumpt werden oder extern serialisiert werden, weil da auch der Datenbankzugriff - für diesenuser drinsteht.

  • Enthält unter anderem Listenbegrenzung vclimit, - Datumsformat dateformat und Nummernformat numberformat

  • Enthält Datenbankzugriffinformationen

- %::myconfig ist im Moment der Ersatz für + für diesen user drinsteht.

  • Enthält unter anderem Listenbegrenzung vclimit, + Datumsformat dateformat und Nummernformat numberformat

  • Enthält Datenbankzugriffinformationen

  • + %::myconfig ist im Moment der Ersatz für ein Userobjekt. Die meisten Funktionen, die etwas anhand des - aktuellen Users entscheiden müssen, befragen - %::myconfig.

    4.1.3.3. $::locale

    • Objekt der Klasse "Locale"

    • Wird pro Request erstellt

    • Muss auch für Tests und Scripte immer verfügbar - sein.

    • Cached intern über Requestgrenzen hinweg benutzte - Locales

    Lokalisierung für den aktuellen User. Alle Übersetzungen, - Zahlen- und Datumsformatierungen laufen über dieses Objekt.

    4.1.3.4. $::lxdebug

    • Objekt der Klasse "LXDebug"

    • Wird global gecached

    • Muss immer verfügbar sein, in nahezu allen + aktuellen Users entscheiden müssen, befragen + %::myconfig. Innerhalb der Anwendungen sind dies + überwiegend die Daten, die sich unter Programm + -> Einstellungen befinden, bzw. die + Informationen über den Benutzer die über die + Administrator-Schnittstelle (admin.pl) eingegeben wurden.

    4.1.3.3. $::locale

    • Objekt der Klasse "Locale"

    • Wird pro Request erstellt

    • Muss auch für Tests und Scripte immer verfügbar + sein.

    • Cached intern über Requestgrenzen hinweg benutzte + Locales

    Lokalisierung für den aktuellen User. Alle Übersetzungen, + Zahlen- und Datumsformatierungen laufen über dieses Objekt.

    4.1.3.4. $::lxdebug

    • Objekt der Klasse "LXDebug"

    • Wird global gecached

    • Muss immer verfügbar sein, in nahezu allen Funktionen

    $::lxdebug stellt Debuggingfunktionen bereit, wie "enter_sub" und @@ -102,52 +133,59 @@ brauchbares Tracing gebaut ist, "log_time", mit der man die Wallclockzeit seit Requeststart loggen kann, sowie "message" und "dump" mit - denen man flott Informationen ins Log packen kann.

    4.1.3.5. $::auth

    • Objekt der Klasse "SL::Auth"

    • Wird global gecached

    • Hat eine permanente DB Verbindung zur Authdatenbank

    • Wird nach jedem Request resettet.

    + denen man flott Informationen ins Log (tmp/kivitendo-debug.log) + packen kann.

    Beispielsweise so:

    $main::lxdebug->message(0, 'Meine Konfig:' . Dumper (%::myconfig));
    +$main::lxdebug->message(0, 'Wer bin ich? Kunde oder Lieferant:' . $form->{vc});

    4.1.3.5. $::auth

    • Objekt der Klasse "SL::Auth"

    • Wird global gecached

    • Hat eine permanente DB Verbindung zur Authdatenbank

    • Wird nach jedem Request resettet.

    $::auth stellt Funktionen bereit um die Rechte des aktuellen Users abzufragen. Obwohl diese Informationen - vom aktuellen User abhängen wird das Objekt aus - Geschwindigkeitsgründen nur einmal angelegt und dann nach jedem - Request kurz resettet.

    4.1.3.6. $::lx_office_conf

    • Objekt der Klasse - "SL::LxOfficeConf"

    • Global gecached

    • Repräsentation der - config/lx_office.conf[.default]-Dateien

    Globale Konfiguration. Configdateien werden zum Start gelesen, - und nicht mehr angefasst. Es ist derzeit nicht geplant, dass das - Programm die Konfiguration ändern kann oder sollte.

    Für die folgende Konfigurationsdatei:

    [debug]
    -file = /tmp/lxoffice_debug_log.txt

    ist der Key file im Programm als + vom aktuellen User abhängen wird das Objekt aus + Geschwindigkeitsgründen nur einmal angelegt und dann nach jedem + Request kurz resettet.

    4.1.3.6. $::lx_office_conf

    • Objekt der Klasse + "SL::LxOfficeConf"

    • Global gecached

    • Repräsentation der + config/kivitendo.conf[.default]-Dateien

    Globale Konfiguration. Configdateien werden zum Start gelesen + und danach nicht mehr angefasst. Es ist derzeit nicht geplant, dass + das Programm die Konfiguration ändern kann oder sollte.

    Beispielsweise ist über den Konfigurationseintrag [debug] die + Debug- und Trace-Log-Datei wie folgt konfiguriert und + verfügbar:

    [debug]
    +file = /tmp/kivitendo-debug.log

    ist der Key file im Programm als $::lx_office_conf->{debug}{file} - erreichbar.

    [Warnung]Warnung

    Zugriff auf die Konfiguration erfolgt im Moment über - Hashkeys, sind also nicht gegen Tippfehler abgesichert.

    4.1.3.7. $::instance_conf

    • Objekt der Klasse + erreichbar.

      [Warnung]Warnung

      Zugriff auf die Konfiguration erfolgt im Moment über + Hashkeys, sind also nicht gegen Tippfehler abgesichert.

    4.1.3.7. $::instance_conf

    • Objekt der Klasse "SL::InstanceConfiguration"

    • wird pro Request neu erstellt

    Funktioniert wie $::lx_office_conf, - speichert aber Daten die von der Instanz abhängig sind. Eine Instanz - ist hier eine Mandantendatenbank. Prominentestes Datum ist "eur", - die Information ob Bilanz oder Einnahmenüberschussrechnung gemacht - wird.

    4.1.3.8. $::dispatcher

    • Objekt der Klasse - "SL::Dispatcher"

    • wird pro Serverprozess erstellt.

    • enthält Informationen über die technische Verbindung zum + speichert aber Daten die von der Instanz abhängig sind. Eine Instanz + ist hier eine Mandantendatenbank. Beispielsweise überprüft +

      $::instance_conf->get_inventory_system eq 'perpetual'

      + ob die berüchtigte Bestandsmethode zur Anwendung kommt.

    4.1.3.8. $::dispatcher

    • Objekt der Klasse + "SL::Dispatcher"

    • wird pro Serverprozess erstellt.

    • enthält Informationen über die technische Verbindung zum Server

    Der dritte Punkt ist auch der einzige Grund warum das Objekt global gespeichert wird. Wird vermutlich irgendwann in einem anderen - Objekt untergebracht.

    4.1.3.9. $::request

    • Hashref (evtl später Objekt)

    • Wird pro Request neu initialisiert.

    • Keine Unterstruktur garantiert.

    + Objekt untergebracht.

    4.1.3.9. $::request

    • Hashref (evtl später Objekt)

    • Wird pro Request neu initialisiert.

    • Keine Unterstruktur garantiert.

    $::request ist ein generischer Platz um - Daten "für den aktuellen Request" abzulegen. Sollte nicht für action + Daten "für den aktuellen Request" abzulegen. Sollte nicht für action at a distance benutzt werden, sondern um lokales memoizing zu - ermöglichen, das garantiert am Ende des Requests zerstört + ermöglichen, das garantiert am Ende des Requests zerstört wird.

    Vieles von dem, was im moment in $::form liegt, sollte eigentlich hier liegen. Die groben - Differentialkriterien sind:

    • Kommt es vom User, und soll unverändert wieder an den User? Dann $::form, steht da eh schon

    • Sind es Daten aus der Datenbank, die nur bis zum Ende des Requests gebraucht werden? Dann + Differentialkriterien sind:

      • Kommt es vom User, und soll unverändert wieder an den + User? Dann $::form, steht da eh schon

      • Sind es Daten aus der Datenbank, die nur bis zum Ende des + Requests gebraucht werden? Dann $::request -

      • Muss ich von anderen Teilen des Programms lesend drauf zugreifen? Dann $::request, aber Zugriff über - Wrappermethode

    4.1.4. Ehemalige globale Variablen

    Die folgenden Variablen waren einmal im Programm, und wurden - entfernt.

    4.1.4.1. $::cgi

    • war nötig, weil cookie Methoden nicht als +

    • Muss ich von anderen Teilen des Programms lesend drauf + zugreifen? Dann $::request, aber Zugriff über + Wrappermethode

    4.1.4. Ehemalige globale Variablen

    Die folgenden Variablen waren einmal im Programm, und wurden + entfernt.

    4.1.4.1. $::cgi

    • war nötig, weil cookie Methoden nicht als Klassenfunktionen funktionieren

    • Aufruf als Klasse erzeugt Dummyobjekt was im - Klassennamespace gehalten wird und über Requestgrenzen + Klassennamespace gehalten wird und über Requestgrenzen leaked

    • liegt jetzt unter $::request->{cgi} -

    4.1.4.2. $::all_units

    • war nötig, weil einige Funktionen in Schleifen zum Teil +

    4.1.4.2. $::all_units

    • war nötig, weil einige Funktionen in Schleifen zum Teil ein paar hundert mal pro Request eine Liste der Einheiten brauchen, und de als Parameter durch einen Riesenstack von - Funktionen geschleift werden müssten.

    • Liegt jetzt unter + Funktionen geschleift werden müssten.

    • Liegt jetzt unter $::request->{cache}{all_units}

    • Wird nur in AM->retrieve_all_units() gesetzt oder - gelesen.

    4.1.4.3. %::called_subs

    • wurde benutzt um callsub deep recursions + gelesen.

    4.1.4.3. %::called_subs

    • wurde benutzt um callsub deep recursions abzufangen.

    • Wurde entfernt, weil callsub nur einen Bruchteil der - möglichen Rekursioenen darstellt, und da nie welche - auftreten.

    • komplette recursion protection wurde entfernt.

    \ No newline at end of file + möglichen Rekursioenen darstellt, und da nie welche + auftreten.

  • komplette recursion protection wurde entfernt.

  • \ No newline at end of file