Pergunta

Eu gostaria de entender adequadamente os hashes em Perl. Eu tive que usar o Perl intermitentemente por algum tempo e, principalmente, sempre que preciso fazê -lo, está relacionado principalmente ao processamento de texto.

E toda vez que tenho que lidar com hashes, ele fica confuso. Eu acho a sintaxe muito enigmática para hashes

Uma boa explicação de hashes e referências de hash, suas diferenças, quando forem necessárias etc. seria muito apreciado.

Foi útil?

Solução

Um hash simples está próximo de uma matriz. Suas inicializações parecem parecidas. Primeiro a matriz:

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

Agora vamos representar as mesmas informações com um hash (também conhecido como matriz associativa):

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

Embora eles tenham o mesmo nome, a matriz @last_name e o hash %last_name são completamente independentes.

Com a matriz, se quisermos conhecer o sobrenome de Archie, temos que realizar uma pesquisa linear:

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";

Com o hash, é muito mais direto sintaticamente:

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

Digamos que queremos representar informações com apenas uma estrutura um pouco mais rica:

  • Cleaver (sobrenome)
    • Ala (primeiro nome)
    • Junho (primeiro nome do cônjuge)
  • Flintstone
    • Fred
    • Wilma
  • Bunker
    • Archie
    • Edith

Antes que as referências surgis

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

Internamente, as chaves e valores de %personal_info são todos escalares, mas os valores são um tipo especial de escalar: referências de hash, criadas com {}. As referências nos permitem simular hashes "multidimensionais". Por exemplo, podemos chegar a Wilma via

$personal_info{Flintstone}->{SPOUSE}

Observe que o Perl nos permite omitir setas entre os subscritos, portanto o acima é equivalente a

$personal_info{Flintstone}{SPOUSE}

Isso é muito digitado se você quiser saber mais sobre Fred, então você pode obter uma referência como uma espécie de cursor:

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

Porque $fred No trecho acima está um hashref, a seta é necessária. Se você deixar de fora, mas sabiamente habilitado use strict Para ajudá -lo a capturar esse tipo de erro, o compilador reclamará:

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

As referências Perl são semelhantes aos ponteiros em C e C ++, mas nunca podem ser nulos. Os ponteiros em C e C ++ requerem desreferência e as referências no Perl.

Os parâmetros da função C e C ++ têm semântica de passagem por valor: são apenas cópias, para que as modificações não voltem ao chamador. Se você quiser ver as alterações, precisa passar por um ponteiro. Você pode obter esse efeito com referências em Perl:

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

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

add_barney \%personal_info;

Sem a barra de barriga, add_barney teria recebido uma cópia que é jogada fora assim que o sub retornar.

Observe também o uso da "vírgula de gordura" (=>) acima de. Ele autoquotes a string à sua esquerda e torna as inicializações de hash menos sintaticamente barulhentas.

Outras dicas

A seguir, demonstra como você pode usar uma referência de hash e 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";

Veja também Perldoc Perldsc.

Um hash é um tipo de dados básico no Perl. Ele usa teclas para acessar seu conteúdo.

Um hash ref é uma abreviação de uma referência a um hash. As referências são escalares, que são valores simples. É um valor escalar que contém essencialmente, um ponteiro para o próprio hash real.

Link: Diferença entre hash e hash ref nos fóruns Perl - Ubuntu

Uma diferença também está na sintaxe para excluir. Como C, Perl funciona como este para hashes:

delete $hash{$key};

e para referências de hash

delete $hash_ref->{$key};

o Perl Hash Howto é um ótimo recurso para entender hashes versus hash com referências de hash

Há também outro link Aqui que tem mais informações sobre Perl e referências.

Ver Perldoc Perlreftut que também é acessível na linha de comando do seu próprio computador.

Uma referência é um valor escalar que se refere a uma matriz inteira ou a um hash inteiro (ou a praticamente qualquer outra coisa). Os nomes são um tipo de referência com a qual você já está familiarizado. Pense no presidente dos Estados Unidos: um saco confuso e inconveniente de sangue e ossos. Mas, para falar sobre ele ou representá -lo em um programa de computador, tudo o que você precisa é da corda escalar mais fácil e conveniente "Barack Obama".

As referências em Perl são como nomes para matrizes e hashes. Eles são nomes internos privados da Perl, para que você possa ter certeza de que são inequívocos. Ao contrário de "Barack Obama", uma referência se refere apenas a uma coisa, e você sempre sabe o que se refere. Se você tiver uma referência a uma matriz, poderá recuperar a matriz inteira dela. Se você tiver uma referência a um hash, poderá recuperar todo o hash. Mas a referência ainda é um valor escalar fácil e compacto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top