2010-10-18 20 views
5

Mam następujący (wyidealizowany z błędem) Krótki skrypt w Perlu:Dlaczego mój skrót nie jest niepoprawny?

my %metadata = undef; 
if (defined %metadata) 
{ 
    print "defined"; 
} 

jakiegoś powodu wyjście programu jest zawsze „zdefiniowany”. Ustawienie wartości mieszania jako "niezdefiniowanej" w jakiś sposób sprawia, że ​​jest ona zdefiniowana. Czy jest zdefiniowany jako "niezdefiniowany"?

EDIT:

to wyidealizowany przypadek, starając się odtworzyć problem. Co ja właściwie robi to bardziej jak:

my %metadata = my_sub_function(); 
if (defined %metadata) 
{ 
    print "defined"; 
} 

Gdzie wyjście my_sub_function może być undef() lub zaludnionych hash, a ja tylko chce wydrukować „zdefiniowane” w ostatnim z tych przypadków.

EDIT 2:

Przypadkowo odkryłem, że

if (scalar(keys %metadata) 

zachowuje się poprawnie(), ale jeszcze nie na undef.

+3

robi '' my_sub_function' zrobić zwrot undef' do I podać błąd lub brak danych? Jeśli tak, to powinien raczej wykonać "powrót" zamiast "go". Będzie to interpretowane jako 'undef' w kontekście skalarnym i'() '(pusta lista) w kontekście listowym. –

Odpowiedz

8

Jeśli funkcja zwraca undef a undef jest umieszczony w zmianach hash, Auto-stringification że UNDEF być '' i skończyć z: %metadata = ('' => undef).

Jeśli funkcja potrzebuje wrócić albo undef, () lub właściwego mieszania i trzeba przetestować wszystkie trzy przypadki osobno, sugeruję:

my %metadata = my_sub_function(); 
if (!scalar keys %metadata) { 
    print "An empty list() was returned\n" 
} elsif (
    scalar keys %metadata == 1 and 
    exists $metadata{''} and 
    !defined $metadata{''} 
) { 
    print "undef or '' was returned\n"; 
} else { 
    print "A hash was hopefully returned\n"; 
} 

Można przetestować go z następującymi my_sub_functions :

sub my_sub_function { return()     } # 1st case 
sub my_sub_function { return undef    } # 2nd case 
sub my_sub_function { return (a => 1, b => 2) } # 3rd case 
sub my_sub_function { return qw/not a hash/  } # unhandled case 

okazji włamania

+1

Cudowna; Dziękuję bardzo! Perl zawsze mnie łapie, jak łatwo robi ciężkie rzeczy i jak ciężko niektóre rzeczy, które powinny być proste stają się :) –

8

Spróbuj

my %metadata; 
undef %metadata; 
if (defined %metadata) 
{ 
    print "defined"; 
} 

myślę, że to było po prostu za pomocą "undef" jako dane do wypełnienia hash.

"ostrzeżenia użytku" powiedziałby:

defined(%hash) is deprecated at t.pl line 6. 
    (Maybe you should just omit the defined()?) 
Odd number of elements in hash assignment at t.pl line 4. 
Use of uninitialized value in list assignment at t.pl line 4. 

undef() lub zaludnionych hash

Jeśli naprawdę chcesz, aby odróżnić pustej hash i bez hash, lepiej użyj skrótu (również jaśniejszego do przejścia z podprogramu, bez przechodzenia przez kopie i wszystkiego).

+0

ah, interesujące! Nie widziałem tego błędu w moich dziennikach, a kod, z którego pochodzi, używa ścisłego i używa ostrzeżeń. Próbowałem również bez zdefiniowane (% hash), z jednakowymi wynikami. –

+0

Niestety nie jestem odpowiedzialny za to, co wraca bezpośrednio z podfunkcji, więc muszę pracować z tym, co dostaję :) –

+0

"Używanie zdefiniowanych na agregatach (hashe i tablice) jest przestarzałe. czy pamięć dla tego agregatu została kiedykolwiek przydzielona.To zachowanie może zniknąć w przyszłych wersjach Perla. Zamiast tego powinieneś użyć prostego testu dla rozmiaru ". Twoje obecne podejście może więc nie działać zbyt dobrze. Lepiej porozmawiaj z ludźmi, którzy stworzyli ten podprogram. – Thilo

1

spróbować

%metadata=("1"=>"one"); 
undef %metadata; 
if (%metadata) 
{ 
    print "defined"; 
} 

A jeśli spojrzeć na dokumentację perldoc -f defined, to mówi to sposoby sprawdzania jest przestarzała.

Use of "defined" on aggregates (hashes and arrays) is deprecated. 
2

jeśli widzisz dokumentację defined, można zauważyć, że,

When defined used on a hash element, 
it tells you whether the value is defined, 
not whether the key exists in the hash. 

spróbować proste, if (%a_hash) { print "has hash members\n" }

Uwaga: undef jest wartość zmiennej, która nigdy nie została zainicjowana (lub który został zresetowany za pomocą funkcji undef). The defined function returns true if the value of the expression is not undef.

Powiązane problemy