Frage

    

Diese Frage bereits eine Antwort hier:

         

Tut mir leid, all diesen dummen Fragen, ich habe Schub gewesen in Perl-Programmierung und ich finde es wirklich schwer, wie ein Perl-Programmierer zu denken.

Dumme Frage für heute: I laden ein Rohr getrennte Datei in eine Hash-ID-Feld als Schlüssel verwendet wird, wie so

#open file

my %hash;
while (<MY_FILE>) {
    chomp;

    my ($id, $path, $date) = split /\|/;

    $hash{$id} = {
        "path" => $path,
        "date" => $date
    };
}

Es gibt ein paar Mal, aber wenn ich den Schlüssel tatsächlich braucht der Weg zu sein, weil aus irgendeinem Grund (und nein, es kann nicht geändert werden) ist die ID nicht eindeutig, so dass ich auf die Idee hatte, dass ich könnte sie alle in ein Unterprogramm setzen und den Namen der Variable übergibt als Schlüssel, um es zu benutzen, ein bisschen wie so:

load_hash("path");

sub load_hash {
    my $key = shift;

    #do stuff, and then in while loop
    $hash{${$key}} = #and so on
}

aber in perldb x $ {$ key} ist immer undefiniert, obwohl x $ {path} gibt den Wert in $ PATH.

Gibt es eine Möglichkeit zu tun, was ich bin versucht?

TIA

War es hilfreich?

Lösung

So etwas wie das?

use Carp 'confess';

sub load_hash {
    my $key = shift;

    # ...

    while (...) {
        # ...
        my %line;  # important that this is *inside* the loop
        @line{qw (id path date)} = split /\|/;
        confess "BUG: unknown key '$key'"  unless exists $line{$key};  # error checking
        $hash{$line{$key}} = \%line;
        delete $line{$key};  # assuming you don't want the key value duplicated
    }
}

Andere Tipps

Sie versuchen, „symbolische Referenzen“ zu verwenden. Wenn Sie ein Problem haben und Sie denken: „Hey, ich dieses Problem lösen würde mit symbolischen Referenzen“ Sie haben jetzt zwei Probleme.

Zunächst einmal, sie nur die Arbeit an Globals. Sie haben $path als lexikalisches (nur sichtbar, in dem Block, der sie deklariert wurde) erklärt und damit LOAD_PATH kann es nicht sehen. Nein, nicht machen $path global.

Zweitens schaffen symbolische Refs Spaghetti-Code. Globals sind schlimm genug. Sie können überall zugegriffen werden kann, zu jeder Zeit durch nichts. Mit einem symbolischen Verweis auf eine globale kann man nicht einmal sehen, welche global zugegriffen wird. Dies macht es unmöglich, was zu verfolgen könnte sich ändern, was passiert. Aus diesem Grunde strict schaltet sie aus. Schalten Sie strict und lassen Sie es auf, bis Sie wissen, wann Sie sollten deaktivieren.

Ich bin nicht ganz sicher, was Sie erreichen wollen, aber es scheint, dies in Ordnung ist.

my %hash;
while (<MY_FILE>) {
    chomp;

    my ($id, $path, $date) = split /\|/;

    $hash{$path} = {
        "path" => $path,
        "date" => $date
    };
}

Aber ich würde wahrscheinlich das Parsen der Zeile in eine Funktion bewegen und die Hash-Zuordnung zur Hauptschleife verlassen. die Linie Parsing ist ein klares chunk der Logik und kann vollständig von Zuweisen der Leitung zum Dateihash getrennt werden. Ein gutes Zeichen ist, dass %hash nicht global sein muss.

my %hash;
while (<MY_FILE>) {
    my $line = parse_line($_);

    my $id = $line->{path};
    $hash{$id} = $line;
}


my @fields = qw(id path date);
sub parse_line {
    my $line = shift;
    chomp $line;

    my %data;
    # This is assigning to a hash slice.  Look it up, its handy.
    @data{@fields} = split m{\|}, $line;

    return \%data;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top