$xNeTworKx: verschachtelte Datenstruktur

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

--
Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
  1. 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

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

      --
      Mit Computern lösen wir Probleme, die wir ohne sie gar nicht hätten.
      1. 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