Czy może undef być kluczem mieszania w Perlu?

Odpowiedź — nie.

undef nie może być kluczem mieszania w Perlu. Ale są subtelności, z powodu których może powstać wrażenie, że może. Szczegóły poniżej.

Co to jest hash

Jedna ze struktur danych, która istnieje w języku programowania Perl — to hash. Hesh to неупорядоченный zestaw par wartości. Oto przykład mieszania:

my %h = (
    aa => 1,
    bb => 2,
);

W tym хеше przechowywane dwie pary wartości. W kluczu o nazwie 'aa' przechowywana jest wartość 1, a w kluczu o nazwie 'bb' przechowywane wartość 2. Aby uzyskać te wartości, używają składnia $h{aa} i $h{bb}.

Co to jest undef

undef — to specjalne znaczenie w Perlu, który oznacza brak wartości. Jeśli utworzyć zmienną, ale nie określić jej żadna wartość, to jej wartość będzie akurat undef:

▶ Run
#!/usr/bin/perl

use Data::Dumper;

my $var;

print Dumper $var;

Program wyświetla na ekranie tekst $VAR1 = undef;.

undef jeszcze można dostać, jeśli odwołać się do nieistniejącego elementu tablicy lub do nieistniejącego klucza w хеше. Można oczywiście przypisać undef zmiennej: $var = undef;.

Błędne użycie 1

Oto przykład programu, z którym wydaje się, że undef może być kluczem mieszania:

▶ Run
#!/usr/bin/perl

my %h = (
    undef => 'asdf',
);

print $h{undef};

Program wyświetla tekst asdf. Czyli jakby stworzyliśmy w хеше klucz undef, a potem dostali wartość tego klucza. Ale to nie tak. W tym przykładzie wartość jest przechowywana w kluczu 'undef', czyli ciąg 'undef', a nie prawdziwy undef.

Dzieje się tak z powodu dwóch cech.

Podczas tworzenia mieszania stworzyliśmy w nim parę klucz-wartość za pomocą kodu undef => 'asdf',. W tym przykładzie zastosowano operator =>. Cechą tego operator w tym, że w niektórych sytuacjach może on dostrzec to co jest po lewej stronie jak wiersz. On jakby wnioskuje to co jest po lewej stronie od => w cudzysłów. undef => 'asdf', to faktycznie 'undef' => 'asdf',.

Druga cecha — to jak dostajemy wartość z mieszania przez klucz. Używamy składni $h{undef}. I tu Perl uważa, że to co jest w nawiasach klamrowych — to wiersz. To co tu napisałeś to to samo, co $h{'undef'}.

Można mieć pewność, że rzeczywiście tak jest, jeśli uruchomić skrypt, podłączając specjalny moduł, który zamiast wykonywania kodu, pokazuje jak Perl rozumie ten kod. perl -MO=Deparse script.pl. Oto wnioski:

my(%h) = ('undef', 'asdf');
print $h{'undef'};
script.pl syntax OK

Błędne użycie 2

Oto jeszcze jeden przykład kodu z którego błędnie wydaje się, że undef może być kluczem mieszania. Już wtedy używamy prawdziwy undef, a nie miejsce 'undef':

▶ Run
#!/usr/bin/perl

my $var = undef;

my %h = (
    $var => 'asdf',
);

print $h{$var};

Program wyświetla tekst asdf. Czyli wygląda na to, że my stworzyliśmy wartość w хеше przez klucz undef.

Ale faktycznie, umieściliśmy wartość w kluczu '' (pusty wiersz). Jeśli dopisać na końcu tego programu poleceń use Data::Dumper i warn Dumper \%h;, po uruchomieniu na ekranie będzie widać jak w rzeczywistości wygląda hash:

$VAR1 = {
          '' => 'asdf'
        };

Zmienna $var zawiera w sobie wartość undef, ale przy użyciu $var => 'asdf', i $h{$var} undef zamiana na pusty ciąg ''.

Jeśli dodać do kodu use strict; i use warnings; (co prawie zawsze warto robić), to w wyniku działania programu będzie widać, że Perl ostrzega o takim użyciu:

Use of uninitialized value $var in list assignment at script.pl line 8.
Use of uninitialized value $var in hash element at script.pl line 12.

Cv

undef nie może być wartością klucza w Perl хеше. Klucze w Perl хеше — to zawsze wiersza. (Należy zaznaczyć tylko, że pusty wiersz '' też może być kluczem). A wartości w хеше mogą być zupełnie dowolne i tam bez problemu może być undef.

Inne artykuły