Wiem, co my
jest w Perlu. Definiuje zmienną, która istnieje tylko w zakresie bloku, w którym jest zdefiniowana. Co ma our
zrobić?
Czym się our
różni my
?
Świetne pytanie: czym się our
różni my
i co robi our
?
W podsumowaniu:
Dostępny od Perla 5 my
jest sposobem deklarowania zmiennych nie-pakietowych, którymi są:
$package_name::variable
.Z drugiej strony our
zmienne są zmiennymi pakietowymi, a zatem automatycznie:
$package_name::variable
.Zadeklarowanie zmiennej za pomocą our
pozwala wstępnie określić zmienne w celu ich użycia use strict
bez uzyskiwania ostrzeżeń literowych lub błędów podczas kompilacji. Od Perla 5.6 zastąpił on przestarzały use vars
, który miał jedynie zakres plików, a nie leksykalny jak jest our
.
Na przykład formalna, kwalifikowana nazwa zmiennej $x
wewnątrz package main
to $main::x
. Zadeklarowanie our $x
pozwala na użycie $x
zmiennej gołej bez kary (tj. Bez błędu wynikowego), w zakresie deklaracji, gdy skrypt używa use strict
lub use strict "vars"
. Zakres może obejmować jeden, dwa lub więcej pakietów lub jeden mały blok.
local
nie tworzy zmiennych. To nie odnosi się domy
iour
w ogóle.local
tymczasowo tworzy kopię zapasową wartości zmiennej i kasuje jej bieżącą wartość.our
zmienne nie są zmiennymi pakietowymi. Nie mają one zasięgu globalnego, ale zmienne o zasięgu leksykalnym, podobnie jakmy
zmienne. Widać, że w następującym programie:package Foo; our $x = 123; package Bar; say $x;
. Jeśli chcesz „zadeklarować” zmienną pakietu, musisz użyćuse vars qw( $x );
.our $x;
deklaruje zmienną o zasięgu leksykalnym, która jest aliasowana do zmiennej o tej samej nazwie w pakiecie, w którymour
została skompilowana.Linki PerlMonks i PerlDoc od Cartmana i Olafura są świetnym odniesieniem - poniżej moje podsumowanie:
my
zmienne mają zasięg leksykalny w obrębie jednego bloku zdefiniowanego przez{}
ten sam plik lub w obrębie tego samego pliku, jeśli nie{}
jest to s. Nie są dostępne z pakietów / podprogramów zdefiniowanych poza tym samym zakresem / blokiem leksykalnym.our
Zmienne mają zasięg w pakiecie / pliku i są dostępne z dowolnego kodu tegouse
lubrequire
tego pakietu / pliku - konflikty nazw są rozwiązywane między pakietami przez dodanie odpowiedniej przestrzeni nazw.Aby to podsumować,
local
zmienne mają zakres „dynamiczny”, różniący się odmy
zmiennych tym, że są również dostępne z podprogramów wywoływanych w tym samym bloku.źródło
my
zmiennych ma zasięg [...] leksykalny w tym samym pliku, jeśli nie jest w{}
s”. To mi się przydało, dzięki.Przykład:
źródło
Radzenie sobie z Scopingiem jest dobrym przeglądem zasad scopingu Perla. Jest wystarczająco stary, że
our
nie jest omawiany w tekście. Jest to omówione w części Notatki na końcu.W artykule omówiono zmienne pakietu i zakres dynamiczny oraz różnice między nimi a zmiennymi leksykalnymi i zakresem leksykalnym.
źródło
my
służy do zmiennych lokalnych, natomiastour
do zmiennych globalnych.Więcej lektur w Variable Scoping w Perlu: podstawy .
źródło
${^Potato}
jest globalny. Odnosi się do tej samej zmiennej, niezależnie od tego, gdzie jej używasz.Zetknąłem się kiedyś z pewnymi pułapkami związanymi z deklaracjami leksykalnymi w Perlu, które mnie zawiodły, które są również związane z tym pytaniem, więc dodam tutaj moje streszczenie:
1. Definicja lub deklaracja?
Dane wyjściowe to
var: 42
. Nie mogliśmy jednak stwierdzić, czylocal $var = 42;
jest to definicja czy deklaracja. Ale co z tym:Drugi program zgłosi błąd:
$var
nie jest zdefiniowany, co oznaczalocal $var;
tylko deklarację! Przed użyciemlocal
do zadeklarowania zmiennej upewnij się, że jest ona wcześniej zdefiniowana jako zmienna globalna.Ale dlaczego to nie zawiedzie?
Wyjście jest:
var: 42
.To dlatego
$a
, że oprócz tego$b
jest globalną zmienną predefiniowaną w Perlu. Pamiętasz funkcję sortowania ?2. Leksykalny czy globalny?
Byłem programistą C, zanim zacząłem używać Perla, więc koncepcja zmiennych leksykalnych i globalnych wydaje mi się prosta: po prostu odpowiada zmiennym auto i zewnętrznym w C. Ale są małe różnice:
W C zmienna zewnętrzna jest zmienną zdefiniowaną poza dowolnym blokiem funkcyjnym. Z drugiej strony zmienna automatyczna to zmienna zdefiniowana w bloku funkcyjnym. Lubię to:
W Perlu rzeczy są subtelne:
Dane wyjściowe to
var: 42
.$var
jest zmienną globalną, nawet jeśli jest zdefiniowana w bloku funkcyjnym! W rzeczywistości w Perlu każda zmienna jest domyślnie deklarowana jako globalna.Lekcja polega na tym, aby zawsze dodawać
use strict; use warnings;
na początku programu Perl, co zmusi programistę do jawnego zadeklarowania zmiennej leksykalnej, abyśmy nie pomylili się z błędami przyjętymi za pewnik.źródło
Perldoc ma dobrą definicję naszego.
źródło
Jest to tylko w pewnym stopniu związane z pytaniem, ale właśnie odkryłem (dla mnie) nieco niejasną składnię perla, której można używać ze zmiennymi „our” (pakiet), których nie można używać z „my” (lokalnie) zmienne.
Wynik:
To nie zadziała, jeśli zmienisz „nasze” na „moje”.
źródło
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
wyjście:barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
wyjście:barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
wyjście:barbar
Więc w moich testach wpadłem w tę samą pułapkę. $ {foo} jest tym samym co $ foo, nawiasy są przydatne podczas interpolacji. $ {„foo”} to tak naprawdę spojrzenie do $ main :: {}, która jest główną tabelą symboli, ponieważ zawiera tylko zmienne o zasięgu pakietowym.perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
, ponieważ w tym kontekście $ {„foo”} jest teraz równe $ {„test :: foo”}. Tabele symboli i globusy zawiera pewne informacje, podobnie jak książka programowania Advanced Perl. Przepraszam za mój poprzedni błąd.Wyprowadzi to:
W przypadku, gdy użycie „użyj ścisłego” spowoduje błąd podczas próby uruchomienia skryptu:
źródło
Spróbuj użyć następującego programu:
źródło
źródło
our
i czym sięmy
różnią? Jak pokazuje ten przykład?Zastanówmy się, czym tak naprawdę jest interpreter: jest to fragment kodu, który przechowuje wartości w pamięci i pozwala instrukcjom w interpretowanym programie na dostęp do tych wartości po ich nazwach, które są określone w tych instrukcjach. Tak więc wielkim zadaniem tłumacza jest kształtowanie zasad, w jaki sposób powinniśmy używać nazw w tych instrukcjach, aby uzyskać dostęp do wartości przechowywanych przez tłumacza.
Po napotkaniu „moje” interpreter tworzy zmienną leksykalną: nazwaną wartość, do której interpreter może uzyskać dostęp tylko podczas wykonywania bloku i tylko z tego bloku składniowego. Po napotkaniu „nasz” interpreter tworzy aleksualny alias zmiennej pakietowej: wiąże nazwę, którą interpreter powinien odtąd przetwarzać jako nazwę zmiennej leksykalnej, aż do zakończenia bloku, do wartości pakietu zmienna o tej samej nazwie.
W efekcie możesz udawać, że używasz zmiennej leksykalnej i omijasz zasady „używaj surowo” przy pełnej kwalifikacji zmiennych pakietowych. Ponieważ interpreter automatycznie tworzy zmienne pakietu przy ich pierwszym użyciu, efektem ubocznym użycia „nasz” może być również to, że interpreter tworzy również zmienną pakietu. W tym przypadku tworzone są dwie rzeczy: zmienna pakietu, do której interpreter może uzyskać dostęp z dowolnego miejsca, pod warunkiem, że jest odpowiednio oznaczona zgodnie z żądaniem wyrażenia „ścisłe użycie” (z nazwą pakietu i dwóch dwukropków) oraz alias leksykalny.
Źródła:
źródło