verschachtelte Datenstruktur
$xNeTworKx
- perl
Hallo,
ich habe folgende Problemstellung :
Aus einer Eingabe werden Name und Passwort eingelesen und an die Subroutine übergeben.
In der Subroutine soll nun geprüft werden, ob der Name mit dem zugehörigen Passwort auch in den "Userdateien" vorkommt. Wenn ja, soll der Dateiname zurückgeliefert werden, in dem der Name und das Passwort vorkommt.
Zuerst dachte ich an eine Lösung mit Hashes, aber ich habe ja 3 Elemente, wodurch ich dann an ein Array auf ein Array dachte.
Dummerweise hab ich von verschachtelten Datenstrukturen nur wenig Ahnung, was die ganze Sache ziemlich erschwert.
Im Moment liefert die Subroutine noch nicht die gewüschte Datei zurück, und ich habe wirklich keine blassen Schimmer, was alles falsch sein könnte, aber vielleicht könnte mal jemand ein Blick darauf werfen, danke.
http://test.acid4u.com/checkentry.txt
Halihallo $xNeTworKx
In der Subroutine soll nun geprüft werden, ob der Name mit dem zugehörigen Passwort auch in den "Userdateien" vorkommt. Wenn ja, soll der Dateiname zurückgeliefert werden, in dem der Name und das Passwort vorkommt.
Warum also erst _alle_ Daten einlesen? - Es wäre wesentlich klüger, jede Datei
einzulesen, die relevanten Daten zu extrahieren und mit den Prozedurparametern zu
vergleichen, falls übereinstimmung zurückgeben. Das spart a) Speicher b) Performance.
Zuerst dachte ich an eine Lösung mit Hashes, aber ich habe ja 3 Elemente, wodurch ich dann an ein Array auf ein Array dachte.
Hash wäre, wenn ich alles richtig durchschaut habe, klüger. Der Hashkey wäre Username,
Hashvalue eine Arrayreferenz mit Pwd und Dateiname. Am Ende könntest du auf den Hash mit
dem Usernamen aus den Prozedurparametern zugreifen und hättest deine Daten; falls Wert
undef existiert der User nicht.
Du schreibst in deinem Beispiel:
@{ $members[$i] }[0..2] = (lc $inputname,$inputpasswort,$_);
damit setzt du einen Splice (Teil des Arrays) mit neuen Werten, das ist nicht in deinem
Sinne, richtig wäre:
$members[$i] = [lc $inputname, $inputpasswort, $_]
also: Du hast ein Array @members; jeder neue Member trägt den Index $i. An der Stelle
$i, wird nun ein neuer Member eingefügt. Was ist dieser Member? - Richtig, nach deiner
Aussage ein neues Array. Aber: Ein Element eines Arrays ist und wird es immer bleiben:
ein _Skalar_; wenn du also "Arraydaten" in einem Element eines Arrays speichern musst,
musst du eine Arrayreferenz bilden (mit den eckigen Klammern), denn nur eine
Arrayreferenz ist ein Skalar. Ich glaube du wurdest schon einige male auf
perldoc perlref | perldata | perlreftut | perllol (letzteres solltest du dir vorallem
mal ansehen, da genau für dein jetztiges Vorhaben relevant) verwiesen, du solltest es
wirklich mal durchlesen.
Dummerweise hab ich von verschachtelten Datenstrukturen nur wenig Ahnung, was die ganze Sache ziemlich erschwert.
s. oben
Im Moment liefert die Subroutine noch nicht die gewüschte Datei zurück, und ich habe wirklich keine blassen Schimmer, was alles falsch sein könnte, aber vielleicht könnte mal jemand ein Blick darauf werfen, danke.
while (defined($_ = readdir(DIR))) {
^^^^
ist nicht ratsam, wohl möglich, aber nicht ratsam. $_ ist sozusagen eine "Systemvariable"
und diese solltest du wirklich nicht selber setzen. Verwende stattdessen einen sinnvollen
Namen.
Und wie ganz oben geschrieben: Deine Datenstruktur brauchst du gar nicht, sie
verschwendet nur Performance und Speicher!
Viele Grüsse und HTH
Philipp
Hallo Philipp
Ich habe es jetzt überhaupt ganz einfach gelöst :
open(FILE,"users/$_") or die "An error occured with $_ : $!\nPlease contact $mailadmin to report this error.\n";
flock FILE, 2;
local $/;
my $input = <FILE>;
close FILE;
my $inputname = $1 if $input =~ /<name>(.+?)</name>/;
my $inputpasswort = $1 if $input =~ /<passwort>(.+?)</passwort>/;
if ((lc $name eq lc $inputname) && ($passwort eq $inputpasswort)) {
$$error = '';
return $_;
}
War um diese Zeit gestern schon ein wenig eingerostet :)
while (defined($_ = readdir(DIR))) {
^^^^
ist nicht ratsam, wohl möglich, aber nicht ratsam. $_ ist sozusagen eine "Systemvariable"
und diese solltest du wirklich nicht selber setzen. Verwende stattdessen einen sinnvollen
Namen.
Ich verstehe nicht ganz warum es klüger sein soll, wenn ich erst einer Variable zuweisen soll, um dann die Daten wieder aus der Variable zu holen? Wenn ich sie gleich aus $_ hole, wäre es doch klüger, oder doch nicht?
$xNeTworKx.
Halihallo $xNeTworKx
Ich habe es jetzt überhaupt ganz einfach gelöst :
... und das war genau die Lösung, die ich andeuten wollte ;)
War um diese Zeit gestern schon ein wenig eingerostet :)
while (defined($_ = readdir(DIR))) {
^^^^ist nicht ratsam, wohl möglich, aber nicht ratsam. $_ ist sozusagen eine "Systemvariable"
und diese solltest du wirklich nicht selber setzen. Verwende stattdessen einen sinnvollen
Namen.Ich verstehe nicht ganz warum es klüger sein soll, wenn ich erst einer Variable zuweisen soll, um dann die Daten wieder aus der Variable zu holen? Wenn ich sie gleich aus $_ hole, wäre es doch klüger, oder doch nicht?
Was heisst denn hier "gleich aus $_ holen"? - $_ ist genauso eine Variable, wie $line
oder $entry. Nur, dass sie eben durch den Perlkontext evtl. schon definiert ist; und
genau dieser Umstand liess mich dazu verleiten, dich darauf aufmerksam zu machen.
Für Perl spielt es keinen Unterschied, ob du dort $_ oder $dir_entry einsetzt, nur,
dass es evtl. zu Problemen führen könnte, wenn erstere durch den Kontext von Perl selber
wieder (um-)gesetzt wird. $_ sollte man eben nur dann gebrauchen, wenn sie durch
Perl selber gesetzt wurde.
Viele Grüsse
Philipp