Operator defined w Perl sprawdza, czy wartość jest zdefiniowana (czy nie jest undef). Ważne jest, aby rozróżniać:
defined($x) zwróci true, jeśli $x nie jest równe undef (niezależnie od wartości, nawet jeśli to pusty ciąg lub 0).defined($hash{$key}) sprawdza, czy wartość elementu jest zdefiniowana, ale nie gwarantuje, że sam klucz istnieje.defined($array[$i]) — podobnie, element może być zdefiniowany, ale tablica może mieć różną długość.exists.Przykład:
my %h = (a => undef); if (exists $h{a}) { print "Klucz 'a' istnieje "; } if (defined $h{a}) { print "Klucz 'a' jest zdefiniowany "; } else { print "Klucz 'a' nie jest zdefiniowany "; }
Wynik:
Klucz 'a' istnieje
Klucz 'a' nie jest zdefiniowany
Czym się różni
exists $hash{$key}oddefined $hash{$key}i kiedy sprawdzenie na defined dla hashy da nieoczekiwany wynik?
Odpowiedź: defined $hash{$key} sprawdza wartość, ale jeśli klucz nie istnieje, zwróci wartość nieokreśloną. Jeśli klucz istnieje, ale jego wartość to undef, defined zwróci false. Ale jeśli klucza nie ma — również false. Dlatego do sprawdzenia istnienia klucza zawsze używaj exists.
Przykład:
my %h = (foo => undef); if (defined $h{foo}) { ... } # false if (exists $h{foo}) { ... } # true
Historia
W jednym projekcie sprawdzano flagę "gotowości" jako
defined($status{$id}), i jeśli wartością była undef, uznawano zadanie za nieprzetworzone. Jednak klucze z undef były ważne, a sprawdzenie exists nie było — w konsekwencji część przetworzonych danych uruchamiano ponownie.
Historia
Programista importując dane z pliku, porównywał ciągi w ten sposób:
if (defined $line && $line ne ''). Problem: czasami $line mógł być zerowym ciągiem '0'. Taki ciąg nie jest pusty, ale porównanie z defined (zamiast sprawdzenia ne '') prowadziło do utraty tych ciągów.
Historia
W dużym skrypcie Perl, który pracował z hashami, jedyną kontrolą istnienia elementu był defined — w wyniku tego dla kluczy o wartości undef pojawiały się błędy i brakujące dane w raportach.