2014-04-14 12 views
6

patrzę na niektóre kodu, ale nie rozumiem, co się następujący wiersz robi/kontroli:Co oznacza ta linia w Perlu?

return if !%Foo::Details:: ; 

Co dokładnie to robi? Czy sprawdza istnienie modułu Foo :: Details?

+3

Wygląda na naprawdę kiepski sposób sprawdzenia, czy moduł został załadowany do tabeli symboli. '% Foo :: Details' to wpis tablicy symboli dla pakietu' Foo :: Details', jeśli nie jest załadowany, zwróci wartość false, która po zanegowaniu zwraca wartość true. Spójrz na ['sekcję tabeli symboli perlmod'] (http://perldoc.perl.org/perlmod.html#Symbol-Tables) –

+0

@HunterMcMillen Myślę, że to jest eleganckie, oparte wyłącznie na jego zwartości. Co dokładnie czyni go ubogim? – Jarmund

+1

Nie jest bardzo jasne (na początku), co robi ten fragment kodu, dlatego myślę, że to jest * słabe *. Są lepsze, bardziej czytelne rozwiązania. –

Odpowiedz

9

Hash w kontekście skalarnym zwraca wartość false, jeśli jest pusta, więc Twój kod zwraca pustą listę, jeśli mieszanie %Foo::Details:: jest puste. To jest tablica symboli dla przestrzeni nazw Foo::Details. Jeśli w przestrzeni nazw Foo::Details zostanie utworzona zmienna pakietu lub podrzędna, zostanie utworzony glob odpowiadający nazwie zmiennej lub podrzędnej w %Foo::Details::. Tak więc zwraca pustą listę, jeśli przestrzeń nazw Foo :: Details jest pusta.

$ cat >Foo/Details.pm 
package Foo::Details; 
sub boo { } 
1; 

$ perl -E'say %Foo::Details:: ?1:0;' 
0 

$ perl -E'use Foo::Details; say %Foo::Details:: ?1:0;' 
1 

Może to być próba sprawdzenia, czy moduł Foo :: Details został załadowany, ale nie jest doskonały. Na przykład będzie myślał, że Foo :: Details został załadowany, nawet jeśli załadowano tylko Foo :: Details :: Bar. Aby sprawdzić, czy załadowano Foo :: Details, lepiej sprawdzić, czy $INC{"Foo/Details.pm"} jest prawdziwe. Problem z tym podejściem polega na tym, że nie znajdzie "wbudowanych modułów".

3

Ten kod sprawdza, czy moduł został załadowany. %Foo::Details:: to tabela symboli dla modułu Foo::Details.

Jeśli Foo::Details nigdy nie został załadowany %Foo::Details:: zwróci false (ponieważ nie zawiera żadnych elementów), które, gdy zanegowany z ! zwróci true i powrót z co funkcja jesteś w.

można przeczytać więcej na temat tabel symboli w perlmod#Symbol Tables

Również, here is another SO post, który mówi o sposobach określenia, czy moduł został załadowany.

+0

bardziej poprawny, aby powiedzieć% Foo :: Szczegóły :: * jest * tablica symboli dla modułu – ysth

+0

Drugi akapit jest nieprawidłowy. Zobacz moją odpowiedź. – ikegami

+0

Czy to technicznie nie jest wpis? Ponieważ jest przechowywany w '% main ::'? –