2010-02-25 14 views
6

Dlaczego ten odcisk 42:Dlaczego nie mogę użyć wartości zmiennej Perla, aby uzyskać dostęp do nazwy zmiennej leksykalnej?

$answer = 42; 
$variable = "answer"; 

print ${$variable} . "\n"; 

ale to nie:

my $answer = 42; 
my $variable = "answer"; 

print ${$variable} . "\n"; 
+0

Zgaduję, że $ odpowiedź definiuje zasięg globalny, a moja $ odpowiedź definiuje zasięg lokalny. –

+0

@Paul, ale print $ answer będzie działał dobrze ... w jaki sposób $ {$ variable} tworzy zasięg globalny? – ennuikiller

+2

Zawsze używaj 'use strict; użyj ostrzeżenia; 'i nigdy nie zobaczysz tego problemu. Co więcej, nigdy nie używaj wartości zmiennej do uzyskania innej zmiennej. Hashe są znacznie lepsze. – Ether

Odpowiedz

15

Tylko zmienne pakietowe (rodzaj zadeklarowany w pierwszym przykładzie) mogą być kierowane za pomocą odniesień symbolicznych. Zmienne leksykalne (my) nie mogą być, dlatego Twój drugi przykład kończy się niepowodzeniem.

Zobacz doskonały artykuł Coping with Scoping, w jaki sposób działają dwa oddzielne systemy zmiennych w języku Perl. Zobacz także doskonałą Why it's stupid to use a variable variable name, dlaczego jest to głupie. :)

6

Perl posiada dwa całkowicie odrębne, ale w dużej mierze kompatybilne systemy zmienne, zmienne opakowaniu, jak w pierwszym przykładzie, i leksykalne zmienne, tak jak w drugim. Jest kilka rzeczy, które każdy może zrobić, ale z drugiej strony nie mogę:

zmienne opakowania są jedynymi, które mogą być:

  1. zlokalizowaną (z local)
  2. użyte jako cel dla symbolicznym odniesieniem (powód drugi przykład praca robi pO za)
  3. stosowany jako gołe słowa (definicje sub, uchwyty plików)
  4. stosować Typeglob (bo to właśnie symbol naprawdę jest pod maską)

Zmienne leksykalne są jedynymi, które można zamknąć (używane w zamknięciu leksykalnym).

Korzystanie ze ścisłej pomocy pomogłoby Ci zadeklarować zmienne pakietu za pomocą our, dzięki czemu różnica jest większa.

Istnieje kilka razy, gdzie odniesienia symboliczne są użyteczne w Perlu, najczęściej koncentrują się wokół manipulacji tablicę symboli (jak pisanie własnego import w module zamiast używać Exporter, małpa-łatanie modułów przy starcie, różne inne zadania meta-programowania). Wszystko to są zaawansowane tematy.

W przypadku innych zadań zwykle jest lepszy sposób na zrobienie tego, na przykład za pomocą skrótu. Ogólna zasada polega na tym, aby zawsze uruchamiać pod numerem use warnings; use strict;, chyba że nie ma innego sposobu niż wyłączenie części pragmy (np. Użycie no strict 'refs'; w jak najmniejszym zakresie).

4

Problem polega na tym, że nie można użyć odniesienia symbolicznego do odniesienia do zmiennej leksykalnej. W obu przykładach ${$variable} szuka $main::answer. W pierwszym, $answer jest pakiet globalny i krótki dla $main::answer, więc referencja znajdzie go. W drugim, $answer jest zmienną leksykalną i nie występuje w żadnej paczce, więc referencja nie może jej znaleźć.

Więcej informacji pod numerem perlref w pozycji Symbolic references.

5

Referencje symboliczne działają tylko ze zmiennymi pakietu. Tablica symboli nie śledzi zmiennych leksykalnych (których cały punkt jest leksykalny :).

Powiązane problemy