Domanda

Vorrei capire correttamente gli hash in Perl. Ho dovuto usare il Perl in modo intermittente per un bel po 'di tempo e soprattutto quando ho bisogno di farlo, è principalmente legato all'elaborazione del testo.

E ogni volta, devo fare i conti con gli hash, si incasina. Trovo la sintassi molto criptica per gli hash

Sarebbe molto apprezzata una buona spiegazione degli hash e dei riferimenti hash, delle loro differenze, quando sono richiesti ecc.

È stato utile?

Soluzione

Un hash semplice è vicino a un array. Le loro inizializzazioni sembrano persino simili. Innanzitutto l'array:

@last_name = (
  "Ward",   "Cleaver",
  "Fred",   "Flintstone",
  "Archie", "Bunker"
);

Ora rappresentiamo le stesse informazioni con un hash (aka array associativo):

%last_name = (
  "Ward",   "Cleaver",
  "Fred",   "Flintstone",
  "Archie", "Bunker"
);

Sebbene abbiano lo stesso nome, l'array @last_name e l'hash % last_name sono completamente indipendenti.

Con l'array, se vogliamo conoscere il cognome di Archie, dobbiamo eseguire una ricerca lineare:

my $lname;
for (my $i = 0; $i < @last_name; $i += 2) {
  $lname = $last_name[$i+1] if $last_name[$i] eq "Archie";
}
print "Archie $lname\n";

Con l'hash, è molto più sintatticamente diretto:

print "Archie $last_name{Archie}\n";

Supponiamo di voler rappresentare informazioni con una struttura solo leggermente più ricca:

  • Cleaver (cognome)
    • Ward (nome)
    • giugno (nome del coniuge)
  • Flintstone
    • Fred
    • Wilma
  • Bunker
    • Archie
    • Edith

Prima che arrivassero i riferimenti, gli hash chiave-valore chiave erano il meglio che potevamo fare, ma i riferimenti lo consentono

my %personal_info = (
    "Cleaver", {
        "FIRST",  "Ward",
        "SPOUSE", "June",
    },
    "Flintstone", {
        "FIRST",  "Fred",
        "SPOUSE", "Wilma",
    },
    "Bunker", {
        "FIRST",  "Archie",
        "SPOUSE", "Edith",
    },
);

Internamente, le chiavi e i valori di % personal_info sono tutti scalari, ma i valori sono un tipo speciale di scalare: riferimenti hash, creati con {} . I riferimenti ci consentono di simulare "multi-dimensionale" hash. Ad esempio, possiamo arrivare a Wilma tramite

$personal_info{Flintstone}->{SPOUSE}

Nota che Perl ci consente di omettere le frecce tra i pedici, quindi quanto sopra equivale a

$personal_info{Flintstone}{SPOUSE}

È un bel po 'di battitura se vuoi saperne di più su Fred, quindi potresti prendere un riferimento come una specie di cursore:

$fred = $personal_info{Flintstone};
print "Fred's wife is $fred->{SPOUSE}\n";

Poiché $ fred nello snippet sopra è un hashref, la freccia è necessaria. Se lo lasci fuori ma abilmente abilitato usa il rigoroso per aiutarti a individuare questo tipo di errori, il compilatore si lamenterà:

Global symbol "%fred" requires explicit package name at ...

I riferimenti Perl sono simili ai puntatori in C e C ++, ma non possono mai essere nulli. I puntatori in C e C ++ richiedono la dereferenziazione, così come i riferimenti in Perl.

I parametri delle funzioni C e C ++ hanno una semantica pass-by-value: sono solo copie, quindi le modifiche non tornano al chiamante. Se vuoi vedere le modifiche, devi passare un puntatore. Puoi ottenere questo effetto con riferimenti in Perl:

sub add_barney {
    my($personal_info) = @_;

    $personal_info->{Rubble} = {
        FIRST  => "Barney",
        SPOUSE => "Betty",
    };
}

add_barney \%personal_info;

Senza la barra rovesciata, add_barney avrebbe ottenuto una copia che verrà gettata via non appena il sub ritornerà.

Nota anche l'uso della " virgola grassa " ( = > ) sopra. Autoquota la stringa alla sua sinistra e rende le inizializzazioni di hash meno sintatticamente rumorose.

Altri suggerimenti

Di seguito viene illustrato come utilizzare un hash e un riferimento hash:

my %hash = (
    toy    => 'aeroplane',
    colour => 'blue',
);
print "I have an ", $hash{toy}, " which is coloured ", $hash{colour}, "\n";

my $hashref = \%hash;
print "I have an ", $hashref->{toy}, " which is coloured ", $hashref->{colour}, "\n";

Vedi anche perldoc perldsc .

  

Un hash è un tipo di dati di base in Perl.   Usa le chiavi per accedere al suo contenuto.

     

Un hash ref è un'abbreviazione di a   riferimento a un hash. I riferimenti sono   scalari, ovvero valori semplici. È   un valore scalare che contiene   in sostanza, un puntatore al reale   hash stesso.

Link: differenza tra hash e hash ref in perl - Forum di Ubuntu

Una differenza sta anche nella sintassi per l'eliminazione. Come C, perl funziona così per Hash:

delete $hash{$key};

e per i riferimenti hash

delete $hash_ref->{$key};

Il Perl Hash Howto è un ottima risorsa per comprendere hash contro hash con riferimenti hash

Esiste anche un altro link che contiene ulteriori informazioni su perl e riferimenti .

Vedi perldoc perlreftut che è anche accessibile dalla riga di comando del tuo computer.

  

Un riferimento è un valore scalare che si riferisce a un intero array o a un intero hash (o praticamente a qualsiasi altra cosa). I nomi sono un tipo di riferimento con cui hai già familiarità. Pensa al presidente degli Stati Uniti: una borsa disordinata e scomoda di sangue e ossa. Ma per parlare di lui o per rappresentarlo in un programma per computer, tutto ciò di cui hai bisogno è la stringa scalare facile e conveniente "Barack Obama".

     

I riferimenti in Perl sono come nomi di array e hash. Sono i nomi interni e privati ??di Perl, quindi puoi essere sicuro che non siano ambigui. A differenza di "Barack Obama", un riferimento si riferisce solo a una cosa e sai sempre a cosa si riferisce. Se si dispone di un riferimento a un array, è possibile ripristinare l'intero array da esso. Se hai un riferimento a un hash, puoi recuperare l'intero hash. Ma il riferimento è ancora un valore scalare facile e compatto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top