Umgang mit Parametern
Pensky
- perl
Hallo,
ich habe ein grundsätzliches Problem mit der Behandlung von Übergabeparametern und Variablen.
Beispiel:
Das Hauptprogramm Haupt erhält über POST eine Vielzahl von Parametern (p1,p2,...). Diese werden gelesen mit
use CGI qw(param);
my $p1=param('p1');
....
Es ruft diverse Unterroutinen auf im Modul up.pm. Diese Unterroutinen benötigen jeweils eine Teilmenge der im Hauptprogramm verfügbaren Parameter.
Ich sehe nun folgende Varianten:
1. Aufruf der Unterroutinen mit genau den Parametern, die sie benötigen.
In den Unterroutinen Lesen der Parameter mit my ($p1,p3,....) = @_;
Vorteil: Genaue Übersicht über die verwendeten Parametern.
Nachteil: Schreibarbeit, Änderung ggf. in Haupt und Unterprogramm
2. Aufruf aller Unterroutinen mit jeweils allen Parametern.
Die Unterroutinen lesen nur die für sie notwendigen Parameter.
Vorteil: Alle Aufrufe im Hauptprogramm identisch.
Nachteil: ?
3. Keine Übergabe von Parametern im Hauptprogramm.
Das Unterprogramm holt jeweils die für es notwendigen Parameter mit
use CGI qw(param);
my $p1=param('p1');
.....
Vorteil: Einfache Aufrufe im Hauptprogramm.
Nachteil: ?
Welche Variante ist zu empfehlen?
Gibt es weitere, bessere Varianten?
Hi,
- [...]
Nachteil: Schreibarbeit, Änderung ggf. in Haupt und Unterprogramm- Aufruf aller Unterroutinen mit jeweils allen Parametern.
Nachteil: ?
siehe 1.
- Keine Übergabe von Parametern im Hauptprogramm.
Nachteil: ?
Eine globale Prüfung auf Validität des User-Inputs ist nicht mehr möglich. Die Prüfungen müssten in jeder Funktion wiederholt werden.
Welche Variante ist zu empfehlen?
4. Erstellung einer globalen Collection, die beim Aufruf übergeben wird.
Gibt es weitere, bessere Varianten?
Keine Ahnung ;-)
Cheatah
Hallo,
- Keine Übergabe von Parametern im Hauptprogramm.
Nachteil: ?Eine globale Prüfung auf Validität des User-Inputs ist nicht mehr möglich. Die Prüfungen müssten in jeder Funktion wiederholt werden.
Geprüft wird der User-Input im Hauptprogramm. Er wird dort nicht verändert, also müsste er doch in den Unterprogrammen nicht erneut geprüft werden?
Welche Variante ist zu empfehlen?
- Erstellung einer globalen Collection, die beim Aufruf übergeben wird.
Kannst Du mir dies bitte erklären?
Über Google finde ich unter "global collection" nichts brauchbares (zumindest in den ersten von Tausenden von Seiten).
Hi,
Geprüft wird der User-Input im Hauptprogramm. Er wird dort nicht verändert,
statt dessen wird bei jeder Abweichung vom Geforderten abgebrochen? Das mag zwar sicher sein, ist jedoch oft genug entgegen jeder Usability. Viele Fehler bei der Eingabe lassen sich leicht erkennen und korrigieren, ohne sie dem User wieder vorwerfen zu müssen.
also müsste er doch in den Unterprogrammen nicht erneut geprüft werden?
Nicht, wenn Du die veränderten Werte diesen übergibst.
- Erstellung einer globalen Collection, die beim Aufruf übergeben wird.
Kannst Du mir dies bitte erklären?
Über Google finde ich unter "global collection" nichts brauchbares (zumindest in den ersten von Tausenden von Seiten).
Das Wort "global" hast Du im anderen Teil meiner Ausführung offenbar verstanden. "Collection" ist ein Konzept, welches in Perl z.B. durch Listen und Hashes ausgeprägt wird. Die beiden Begriffe zu kombinieren ergibt keine Magie.
Cheatah
Hallo
statt dessen wird bei jeder Abweichung vom Geforderten abgebrochen? Das mag zwar sicher sein, ist jedoch oft genug entgegen jeder Usability. Viele Fehler bei der Eingabe lassen sich leicht erkennen und korrigieren, ohne sie dem User wieder vorwerfen zu müssen.
Es wird nicht abgebrochen, der Anwender kann die Werte korrigieren, dann wird das Hauptprogramm erneut aufgerufen und die Unterprogramme erhalten die neuen Werte.
"Collection" ist ein Konzept, welches in Perl z.B. durch Listen und Hashes ausgeprägt wird. Die beiden Begriffe zu kombinieren ergibt keine Magie.
Ist das deine "Creation"? Auch in Selfhtml finde ich den Begriff nicht als Oberbegriff für Listen und Hashes? Und eine "Sammlung" kann nun alles mögliche sein.
Gruß
Pensky
"Collection" ist ein Konzept, welches in Perl z.B. durch Listen und Hashes ausgeprägt wird. Die beiden Begriffe zu kombinieren ergibt keine Magie.
Ist das deine "Creation"? Auch in Selfhtml finde ich den Begriff nicht als Oberbegriff für Listen und Hashes? Und eine "Sammlung" kann nun alles mögliche sein.
nein. es ist etwas, das unter einer einzigen Variable oder Referenz angesprochen werden kann.
Lass uns annehmen:
my %UserData = ( somekey => 'somedefaultvalue');
Nach dem Auslesen des Userinputs und nach Validierung hast
%UserData = ( somekey => 'somelegaluservalue',);
Du kannst nun den Hash bequem als Sammlung der User-Daten übergeben:
some_sub_in_some_other_package( %UserData );
in diesem Falle als Referenz.
mfg Beat;
Hi,
statt dessen wird bei jeder Abweichung vom Geforderten abgebrochen? Das mag zwar sicher sein, ist jedoch oft genug entgegen jeder Usability. Viele Fehler bei der Eingabe lassen sich leicht erkennen und korrigieren, ohne sie dem User wieder vorwerfen zu müssen.
Es wird nicht abgebrochen, der Anwender kann die Werte korrigieren,
während das Script läuft? Dann ist mir nicht klar, wie Du Daten per POST erhältst.
"Collection" ist ein Konzept, welches in Perl z.B. durch Listen und Hashes ausgeprägt wird. Die beiden Begriffe zu kombinieren ergibt keine Magie.
Ist das deine "Creation"?
Nein, angewandte Informatik. Und ebensolches Deutsch - auch wenn ein englischsprachiger Begriff drin vorkommt. Wie gesagt ist es keine Magie, in einem Satz mehrere Begriffe zu kombinieren. Es ist sogar richtig, "angewandte" und "Informatik" in einen Zusammenhang zu stellen, um damit auszudrücken, dass Informatik angewendet wurde; und das obwohl es eine Fachrichtung namens "Angewandte Informatik" gibt, die hier nicht gemeint ist.
Auch in Selfhtml finde ich den Begriff nicht als Oberbegriff für Listen und Hashes?
SelfHTML ist kein vollständiges Nachschlagewerk für alle Bereiche rund um die Programmierung.
Und eine "Sammlung" kann nun alles mögliche sein.
Absolut korrekt. Genau das zeichnet den Begriff "Collection" aus.
Cheatah
Hallo,
statt dessen wird bei jeder Abweichung vom Geforderten abgebrochen? Das mag zwar sicher sein, ist jedoch oft genug entgegen jeder Usability. Viele Fehler bei der Eingabe lassen sich leicht erkennen und korrigieren, ohne sie dem User wieder vorwerfen zu müssen.
Es wird nicht abgebrochen, der Anwender kann die Werte korrigieren,während das Script läuft? Dann ist mir nicht klar, wie Du Daten per POST erhältst.
Warum "während das Script läuft"?
Ich nehme an, es ist die normale Formularverarbeitung.
1. Anwender gibt Daten ein und drückt den Submit-Button.
Das Perl-Haupt-Programm wird aufgerufen, prüft die Eingaben unter Verwendung der Unterprogramme.
Wenn Fehler, wird wieder das Formular ausgegeben mit Fehlermeldungen.
Dann geht es wieder bei 1. weiter.
Hi,
Es wird nicht abgebrochen, der Anwender kann die Werte korrigieren,
während das Script läuft? Dann ist mir nicht klar, wie Du Daten per POST erhältst.
Warum "während das Script läuft"?
weil ansonsten das Script zu einem Ende kommt.
Ich nehme an, es ist die normale Formularverarbeitung.
Dann *muss* das Script enden, also laut Deiner Beschreibung der Vorgang abgebrochen werden, wenn die eingegebenen Daten nicht korrekt sind.
Cheatah
Es ruft diverse Unterroutinen auf im Modul up.pm. Diese Unterroutinen benötigen jeweils eine Teilmenge der im Hauptprogramm verfügbaren Parameter.
Ich sehe nun folgende Varianten:
- Aufruf der Unterroutinen mit genau den Parametern, die sie benötigen.
In den Unterroutinen Lesen der Parameter mit my ($p1,p3,....) = @_;
Vorteil: Genaue Übersicht über die verwendeten Parametern.
Nachteil: Schreibarbeit, Änderung ggf. in Haupt und Unterprogramm
Du kannst eine Funktion nie anders aufrufen als mit Parametern, die in Bezug auf die Funktion gültig sind. Was du bei deinem Beispiel nicht erkennst, ist die blödisinnige Festnagelung auf eine Reihenfolge der Argumente.
- Aufruf aller Unterroutinen mit jeweils allen Parametern.
Die Unterroutinen lesen nur die für sie notwendigen Parameter.
Vorteil: Alle Aufrufe im Hauptprogramm identisch.
Nachteil: ?
Speicherplatz. Was übergibst du bei func(%hash)? Eine Kopie.
- Keine Übergabe von Parametern im Hauptprogramm.
Das Unterprogramm holt jeweils die für es notwendigen Parameter mit
use CGI qw(param);
my $p1=param('p1');
.....
Vorteil: Einfache Aufrufe im Hauptprogramm.
Nachteil: ?
Du vertraust darauf, dass der inhalt der CGI Variable gewährleistet ist?
Welche Variante ist zu empfehlen?
Gibt es weitere, bessere Varianten?
Überlege dir den Vorteil, Funktionen in Modulen (und auch in anderen Subs) stets eine Hashreferenz zu übergeben.
modul_func( { key => $val1, key2 => $val2, } )
Für mich erschliesst sich übrigens der Sinn von ausgelagerten Funktionen nicht, es sei denn, diese sind nach Modulrichtilinien mit dokumentierter API versehen.
mfg Beat;
Hallo,
Du vertraust darauf, dass der inhalt der CGI Variable gewährleistet ist?
Warum und wodurch sollte dieser verändert werden?
Überlege dir den Vorteil, Funktionen in Modulen (und auch in anderen Subs) stets eine Hashreferenz zu übergeben.
modul_func( { key => $val1, key2 => $val2, } )
Dann kann aus dem externen Unterprogramm über diese Referenz auf die z.T. lokalen (my) Variablen im Hauptprogramm zugegriffen werden?
Für mich erschliesst sich übrigens der Sinn von ausgelagerten Funktionen nicht, es sei denn, diese sind nach Modulrichtilinien mit dokumentierter API versehen.
Ich möchte erstens keine riesigen Programme und zweitens nicht in jedem Programm z.B. die gleiche Fehlerroutine schreiben.
Gruß
Pensky
Du vertraust darauf, dass der inhalt der CGI Variable gewährleistet ist?
Warum und wodurch sollte dieser verändert werden?
Das ist nicht die Frage. Das CGI Modul gibt dir böse Rohdaten.
In Perl gibt es genau einen Standardprozess, wie du Userdaten untaintest.
Das Prinzip ist
$InputRohdaten{feld1} =~ /(x|y|z)/ and $InputUntainted{feld1} = $1;
Das ist der einzige Weg, Userinput zu untainten.
Um das etwas zu rationalisieren:
foreach( %InputRohdaten ){
/^feld1$/
and $InputRohdaten{$_} =~ /(x|y|z)/
and $InputUntainted{$_} = $1
and next;
/^feld2$/
and $InputRohdaten{$_} =~ /(\d{1,3})/
and $InputUntainted{$_} = $1
and next;
/^feld3$/ and
$InputRohdaten{$_} =~ /([\w-]{10,32})/
and $InputUntainted{$_} = $1
and next;
}
%InputRohdaten = (); # brauchen wir nicht mehr...
Überlege dir den Vorteil, Funktionen in Modulen (und auch in anderen Subs) stets eine Hashreferenz zu übergeben.
modul_func( { key => $val1, key2 => $val2, } )
Dann kann aus dem externen Unterprogramm über diese Referenz auf die z.T. lokalen (my) Variablen im Hauptprogramm zugegriffen werden?
Ja, übergibst du eine Referenz, arbetest du auf dem Original.
Normaler Hash
my %hash = ( key => $val1, key2 => $val2, );
some_func_in_some_package( %hash );
Referenz eines Anonymen hashes mit Klammer {}
my $anonhashref = { key => $val1, key2 => $val2, };
some_func_in_some_package( $anonhashref );
Für mich erschliesst sich übrigens der Sinn von ausgelagerten Funktionen nicht, es sei denn, diese sind nach Modulrichtilinien mit dokumentierter API versehen.
Ich möchte erstens keine riesigen Programme und zweitens nicht in jedem Programm z.B. die gleiche Fehlerroutine schreiben.
Der Programmumfang ist die Summe der Ressourcen.
Mehr Komplexität, mehr Chaos, schlechteres Debugging.
In meinem 5500++ Zeilenprogramm habe ich gerade mal 10 Zeilen Code für Errormessages, die zudem nie innerhalb des letzten Jahres ausgeführt wurden.
Das sollte dir etwas sagen. Musst du Errormessages ausgeben, machst du etwas falsch.
mfg Beat;
Das ist nicht die Frage. Das CGI Modul gibt dir böse Rohdaten.
In Perl gibt es genau einen Standardprozess, wie du Userdaten untaintest.Das Prinzip ist
$InputRohdaten{feld1} =~ /(x|y|z)/ and $InputUntainted{feld1} = $1;Das ist der einzige Weg, Userinput zu untainten.
Um das etwas zu rationalisieren:
foreach( %InputRohdaten ){
/^feld1$/
and $InputRohdaten{$_} =~ /(x|y|z)/
and $InputUntainted{$_} = $1
and next;
/^feld2$/
and $InputRohdaten{$_} =~ /(\d{1,3})/
and $InputUntainted{$_} = $1
and next;
/^feld3$/ and
$InputRohdaten{$_} =~ /([\w-]{10,32})/
and $InputUntainted{$_} = $1
and next;
}
%InputRohdaten = (); # brauchen wir nicht mehr...
So etwas habe ich noch in keinem der angebotenen Kontakt- oder Gästebuchformular-Perl-Programmen gesehen.
Ich verstehe auch leider das obige Konstrukt überhaupt nicht.
Ich prüfe gezielt jedes einzelne Feld ob formal richtig (z.B. numerisch, alphanumerisch etc.) und dann noch auf Plausibilität, gegenseitige Abhängigkeiten etc.
Der Programmumfang ist die Summe der Ressourcen.
Mehr Komplexität, mehr Chaos, schlechteres Debugging.
In meinem 5500++ Zeilenprogramm habe ich gerade mal 10 Zeilen Code für Errormessages, die zudem nie innerhalb des letzten Jahres ausgeführt wurden.
Das sollte dir etwas sagen. Musst du Errormessages ausgeben, machst du etwas falsch.
Auch das ist mir unklar. Für jede fehlerhafte Benutzereingabe gebe ich möglichst gezielt eine Fehlermeldung aus. D.h. zu einem Eingabefeld gibt es mehrere mögliche Fehlermeldungen. Aber selbst wenn ich für alle Fehler nur eine Meldung ausgeben würde "Irgendetwas ist falsch", so gehe ich davon aus, dass innerhalb eines Jahres diese mehrfach ausgegeben würde, es sei denn ich hätte keine Besucher auf meiner Homepage.
Gruß
Pensky
So etwas habe ich noch in keinem der angebotenen Kontakt- oder Gästebuchformular-Perl-Programmen gesehen.
Ich weiss. Die Crackies bringen ihre Trojaner auf den Markt.
Ich verstehe auch leider das obige Konstrukt überhaupt nicht.
Das ist schade. Ändere dein Verständnis.
Ich prüfe gezielt jedes einzelne Feld ob formal richtig (z.B. numerisch, alphanumerisch etc.) und dann noch auf Plausibilität, gegenseitige Abhängigkeiten etc.
Genau dies wird in meinem Post angesprochen.
In meinem 5500++ Zeilenprogramm habe ich gerade mal 10 Zeilen Code für Errormessages, die zudem nie innerhalb des letzten Jahres ausgeführt wurden.
Das sollte dir etwas sagen. Musst du Errormessages ausgeben, machst du etwas falsch.Auch das ist mir unklar. Für jede fehlerhafte Benutzereingabe gebe ich möglichst gezielt eine Fehlermeldung aus. D.h. zu einem Eingabefeld gibt es mehrere mögliche Fehlermeldungen. Aber selbst wenn ich für alle Fehler nur eine Meldung ausgeben würde "Irgendetwas ist falsch", so gehe ich davon aus, dass innerhalb eines Jahres diese mehrfach ausgegeben würde, es sei denn ich hätte keine Besucher auf meiner Homepage.
Ein ERROR hat nichts mit einer ungeeigneten Usereingabe zu tun.
Ungeeigneten Usereingabe werden aber durch schlechte Formularanleitungen begünstigt.
Ungeeignete Usereingaben werden bei mir durch einen Defaultwert ersetzt.
In ganz wenigen Vorgängen muss ich eine informative Warnung ausgeben, weil der Input einer validen Eingabe betrieblich notwendig ist:
zum Beispiel, wenn du einen Account erstellen willst.
Sonst? Nichts. Die Benutzerhilfen bei jedem Formular sollen reichen.
mfg Beat;
Hallo
Ich prüfe gezielt jedes einzelne Feld ob formal richtig (z.B. numerisch, alphanumerisch etc.) und dann noch auf Plausibilität, gegenseitige Abhängigkeiten etc.
Genau dies wird in meinem Post angesprochen.
Plausibilität, gegenseitige Abhängigkeiten?
Ungeeignete Usereingaben werden bei mir durch einen Defaultwert ersetzt.
In ganz wenigen Vorgängen muss ich eine informative Warnung ausgeben, weil der Input einer validen Eingabe betrieblich notwendig ist:
zum Beispiel, wenn du einen Account erstellen willst.
Sonst? Nichts. Die Benutzerhilfen bei jedem Formular sollen reichen.
Das gilt dann aber nur für recht anspruchslose Formulare!
Gruß
Pensky