Thread Hashvergleich klappt nicht *war Anfänger Frage (10 answers)
Opened by der_thomas at 2013-09-22 18:11

topeg
 2013-09-22 23:00
#170511 #170511
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Man muss zwischen == und eq unterscheiden weil Perl automatisch castet.
Ich nehme mal diese Stelle:

$notiz == "\n" bzw. $notiz eq "\n"

Was bei == passiert:
  • Beginnt der Wert in $notiz mit einer gültigen Zahl?
    => nein => setze Zahlenwert von $notiz auf "0"
  • Beginnt der String "\n" mit einer gültigen Zahl?
    => nein => setze Zahlenwert auf "0"
  • Ist 0 == 0 wahr?
    => Ja


Was bei eq passiert:
  • Stimmt der Wert in $notiz binär mit "\n" überein?
    => nein


Zur Fehlermeldung 'Died at perl2.pl line 24.'
Das wird durch das || die bewirkt. open gibt "true" zurück wenn das öffnen einer Datei erfolgreich wahr und 0 bei einem Fehler. die Fehlermeldung findet sich dann in der Spezialvariable $!
Will man also eine etwas ausführlichere Erklärung haben schreibt man etwas in der Art:
Code (perl): (dl )
open( my $FH, '<', 'links.txt' ) or die("ERROR open links.txt ($!)");


Wenn du nicht verstehst was eine Zeile macht dann Frage nach. In den aller meisten Fällen schreiben wir nichts unnötiges in den Code. :-)

weiterhin solltest du bei Rekursionen aufpassen. Das du datensuchen immer wider sich selbst aufruft kann zu einer "deep recursion" Warnung führen. Zudem werden alle Kontexte aus jedem Aufruf im Speicher gehalten. Hier ist das kein Problem, aber man sollte das im Hinterkopf behalten.
Außerdem finde ich hier die iterative Lösung übersichtlicher:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/perl
use v5.12;
use strict;
use warnings;

sub datensuchen {
    # daten übernehmen
    # @_ enthält alle Variablen
    # die an diese Funktion übergeben wurden
    my $data = shift(@_);

    # $data enthält eine Refenz auf den hash "daten"
    # das verändert die Art es Zugriffs auf die Werte im Hash
    # hier ist eine Refenz nützlich,
    # da nicht alle Daten aus %daten in @_ kopiert werden
    # und von da aus in einen neuen Hash ( z.B %data )
    # nur der "Verweis" auf die Werte im Hash %daten werden nach $data kopiert

    print "\nLink suchen (Enter = Beenden)\n";

    my $notiz = <STDIN>;

    # \n entfernen:
    chomp($notiz);

    # variable ist leer.
    # abbruch !
    return 0 if ($notiz eq "");

    # zugriff bei einer Referenz ist mit "->"
    if (exists $data->{$notiz}){
        print "\n$data->{$notiz}\n";
    }
    else {
        print "\nNicht gefunden !!\n";
    }

    return 1;
}

sub datenladen{
    # Kurzschreibweise
    # "shift" benutzt @_ als variable
    # wenn nichts angeben wird
    my $file = shift;

    my %data;

    open( my $FH, '<', $file ) or die("ERROR open $file ($!)");

    # das lesen mit "while"
    # ist nicht so Speicherhungrig
    #

    # zeile mit dem Key lesen
    while(my $key = <$FH>) {
        chomp($key);

        # weiter wenn $key 0, undef, oder einen leeren String enthält
        # das kann passieren wenn am Ende ein Wert fehlt
        # oder zwischendurch leere Zeilen sind, die Keys sein sollten
        next unless($key);

        # Zeile mit dem Wert lesen
        my $val = <$FH>;
        chomp($val);


        # werte zuweisen
        $data{$key} = $val;
    }

    # hash zurück geben
    return %data;
}

# main

# daten laden
my %daten = datenladen('links.txt');

# Eingaben Auswerten:
while( datensuchen(\%daten) ) {
  # nächster Durchlauf
  print "\n---------\n";
}

View full thread Hashvergleich klappt nicht *war Anfänger Frage