Jaka jest różnica między moim a lokalnym w Perlu?

Widzę oba użyte w tym skrypcie staram się debugować i literatura jest po prostu nie jasna. Czy ktoś może mi to wyjaśnić?

Author: skaffman, 2008-09-24

14 answers

Dynamiczny Zasięg. To zgrabna koncepcja. Wiele osób go nie używa ani nie rozumie.

Zasadniczo pomyśl o my jako o stworzeniu i zakotwiczeniu zmiennej w jednym bloku {}, A. K. A. scope.

my $foo if (true); # $foo lives and dies within the if statement.

Więc my zmienna jest tym, do czego jesteś przyzwyczajony. natomiast przy dynamicznym zasięgu $var może być zadeklarowane w dowolnym miejscu i używane w dowolnym miejscu. Więc z local zasadniczo zawieszasz użycie tej zmiennej globalnej i używasz "wartości lokalnej" do pracy z nią. Więc local tworzy tymczasowy zakres dla tymczasowego zmienna.

$var = 4;
print $var, "\n";
&hello;
print $var, "\n";

# subroutines
sub hello {
     local $var = 10;
     print $var, "\n";
     &gogo; # calling subroutine gogo
     print $var, "\n";
}
sub gogo {
     $var ++;
}

To powinno wydrukować:

4
10
11
4
 40
Author: J.J.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-07 14:33:15

Krótka odpowiedź brzmi: my oznacza zmienną jako prywatną w zakresie leksykalnym, a local oznacza zmienną jako prywatną w zakresie dynamicznym.

Jest to łatwiejsze do zrozumienia my, ponieważ tworzy to zmienną lokalną w zwykłym znaczeniu. Powstaje nowa zmienna i jest dostępna tylko w obrębie zamkniętego bloku leksykalnego, który zwykle oznaczany jest nawiasami klamrowymi. Istnieją pewne wyjątki od reguły curly-brace, takie jak:

foreach my $x (@foo) { print "$x\n"; }

Ale to tylko Perl robi to co Ty wredny. Normalnie masz coś takiego:

sub Foo {
   my $x = shift;

   print "$x\n";
}

W takim przypadku, $x jest prywatny podprogramu i jego zakres jest zamknięty nawiasami klamrowymi. Należy zauważyć, że zakres zmiennej local jest zdefiniowany w odniesieniu do Twojego kodu, tak jak jest on zapisany w pliku. To zjawisko w czasie kompilacji.

Aby zrozumieć local, musisz myśleć w kategoriach stosu wywołującego Twojego programu, który jest uruchomiony. Gdy zmienna jest local, jest ona przedefiniowywana od momentu, w którym instrukcja local wykonuje wszystko, co znajduje się poniżej stosu, aż do powrotu do wywołującego blok zawierający local.

Na początku może to być mylące, więc rozważ poniższy przykład.

sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }

$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect

Kiedy foo jest wywoływany po raz pierwszy, widzi globalną wartość $x, która wynosi 1. Gdy bar jest wywołana i local $x działa, to na nowo definiuje globalną $x na stosie. Teraz kiedy foo jest wywoływana z bar, widzi nową wartość 2 dla $x. Jak na razie nie jest to zbyt wyjątkowe, ponieważ to samo mogłoby się wydarzyć bez wezwania do local. Magia polega na tym, że po powrocie bar opuszczamy dynamiczny zakres utworzony przez local $x, A poprzedni globalny $x wraca do zakresu. / Align = "left" / foo, $x 1.

Prawie zawsze będziesz chciał używać my, ponieważ to daje Ci zmienną lokalną, której szukasz. Raz w błękitnym Księżycu, local jest naprawdę przydatny do fajne rzeczy.

 56
Author: Jeremy Bourque,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-15 18:19:29

Cytowanie z Nauka Perla:

Ale local jest błędnie nazwany, lub przynajmniej błędnie nazwany. Nasz przyjaciel Chip Salzenberg mówi, że jeśli kiedykolwiek będzie miał szansę wrócić wehikułem czasu do 1986 roku i dać Larry 'emu jedną radę, powie Larry' emu, aby zadzwonił do lokalnego po imieniu "Zapisz".[14] dzieje się tak dlatego, że local faktycznie zapisze wartość danej zmiennej globalnej, więc zostanie ona później automatycznie przywrócona do zmiennej globalnej. (Zgadza się: te tak zwane "lokalne" zmienne są w rzeczywistości globalnymi!) Ten mechanizm zapisywania i przywracania jest taki sam, jaki widzieliśmy już dwa razy, w zmiennej sterującej pętli foreach oraz w tablicy parametrów podprogramu@_.

Tak więc, local zapisuje bieżącą wartość zmiennej globalnej, a następnie ustaw ją na jakąś formę pustej wartości. Często zobaczysz, że służy do przeciągania całego pliku, a nie tylko prowadzenia linii:

my $file_content;
{
    local $/;
    open IN, "foo.txt";
    $file_content = <IN>;
} 

Wywołanie local $/ ustawia separator rekordów wejściowych (wartość, która Perl przestaje odczytywać" linię " na) do pustej wartości, powodując, że operator statku kosmicznego odczytuje cały plik, więc nigdy nie uderza w separator rekordów wejściowych.

 23
Author: Drew Stephens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 22:58:10

Nie mogę uwierzyć, że nikt nie połączył się z wyczerpującymi rozprawami Marka Jasona Dominusa na ten temat:

 16
Author: Aristotle Pagaltzis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 23:25:27

Http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()

W przeciwieństwie do zmiennych dynamicznych utworzonych przez operator lokalny, zmienne leksykalne zadeklarowane z moim są całkowicie ukryte ze świata zewnętrznego, w tym wszelkie zwane podprogramami. Jest to prawdą, jeśli to ten sam podprogram zwany z siebie lub gdzie indziej-każdy telefon dostaje własną kopię.

Http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()

Lokalny modyfikuje swoje zmienne być "lokalnym" do bloku zamykającego, ewaluacji, lub do pliku --i do dowolnego podprogramu wywołanego z wewnątrz tego blok. Lokalny po prostu daje tymczasowe wartości do global (czyli pakiet) zmienne. Nie tworzy lokalnego zmienna. Jest to znane jako dynamiczne namierzam. Zakres leksykalny odbywa się za pomocą mój, który działa bardziej jak auto C deklaracje.

Nie wydaje mi się to wcale niejasne, poza stwierdzeniem, że przez " lokalne do enclosing block", co oznacza, że oryginalna wartość jest przywracana po zamknięciu bloku.

 9
Author: Steve Jessop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-08 13:11:24

Cóż Google naprawdę działa dla Ciebie na tym jednym: http://www.perlmonks.org/?node_id=94007

From the link:

Szybkie podsumowanie: 'my' tworzy nowy zmienna, "lokalna" tymczasowo zmienia wartość zmiennej.

Ie, ' local 'tymczasowo zmienia wartość zmiennej , ale tylko w zakresie istnieje w

Ogólnie używaj my, jest szybszy i nie robi nic dziwnego.

 7
Author: dlamblin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 20:19:48

From man perlsub:

W przeciwieństwie do zmiennych dynamicznych utworzonych przez operatora lokalnego, zmienne leksykalne zadeklarowane za pomocą my są całkowicie ukryte przed światem zewnętrznym, włączając w to dowolne wywołane podprogramy.

Więc, upraszczając, my sprawia, że Twoja zmienna jest widoczna tylko tam, gdzie jest zadeklarowana. local sprawia, że jest on również widoczny na stosie połączeń. Zazwyczaj będziesz chciał użyć my zamiast local.

 6
Author: catfood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 20:18:10

Twoje zamieszanie jest zrozumiałe. Zakres leksykalny jest dość łatwy do zrozumienia, ale zakres dynamiczny jest niezwykłym pojęciem. Sytuację pogarsza fakt, że nazwy my i local są nieco niedokładne (lub przynajmniej nieintuicyjne) ze względów historycznych.

my deklaruje zmienną leksykalną-taką, która jest widoczna od punktu deklaracji aż do końca bloku (lub pliku). Jest całkowicie niezależny od innych zmiennych o tej samej nazwie w pozostałych program. To prywatna sprawa.

local, z drugiej strony deklaruje tymczasową zmianę wartości zmiennej globalnej. Zmiana kończy się na końcu zakresu, ale zmienna-jako globalna - jest widoczna w dowolnym miejscu programu.

Jako regułę używaj my do deklarowania własnych zmiennych i local do kontrolowania wpływu zmian wbudowanych zmiennych Perla.

Po dokładniejszy opis zobacz artykuł Marka Jasona Dominusa radzenie sobie z Scopingiem .

 4
Author: Michael Carman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 02:00:13

Local jest starszą metodą lokalizacji, z czasów, gdy Perl miał tylko dynamiczny zasięg. Zakres leksykalny jest o wiele bardziej naturalny dla programisty i o wiele bezpieczniejszy w wielu sytuacjach. moje zmienne należą do zakresu (bloku, pakietu lub pliku), w którym są zadeklarowane.

Zmienne lokalne zamiast tego należą do globalnej przestrzeni nazw. Jeśli odnosisz się do zmiennej $x za pomocą local, w rzeczywistości odnosisz się do zmiennej $ main:: x, która jest zmienną globalną. Wbrew nazwie implikuje, że wszystko, co lokalne robi, to wypychanie nowej wartości na stos wartości $main:: x do końca tego bloku, w którym to czasie Stara wartość zostanie przywrócona. Jest to przydatna funkcja sama w sobie, ale nie jest to dobry sposób, aby mieć zmienne lokalne z wielu powodów (pomyśl, co się dzieje, gdy masz wątki! i pomyśl, co się dzieje, gdy nazywasz rutynę, która naprawdę chce używać globalnego, który masz zlokalizowane!). Był to jednak jedyny sposób na posiadanie zmiennych, które wyglądały jak lokalne zmienne w starych złych czasach przed Perlem 5. Nadal z tym tkwimy.

 3
Author: skiphoppy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-25 18:52:22

"moje" zmienne są widoczne tylko w bieżącym bloku kodu. zmienne "lokalne" są również widoczne tam, gdzie kiedykolwiek były widoczne wcześniej. Na przykład, jeśli powiesz "my $X;" i wywołasz podfunkcję, to nie widzi ona tej zmiennej $x. ale jeśli powiesz "local $/;" (aby anulować wartość separatora rekordów), zmienisz sposób odczytu z plików w dowolnych wywołanych funkcjach.

W praktyce prawie zawsze chcesz "moje", a nie "lokalne".

 2
Author: andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-24 20:18:36

Spójrz na poniższy kod i jego wynik, aby zrozumieć różnicę.

our $name = "Abhishek";

sub sub1
{
    print "\nName = $name\n";
    local $name = "Abhijeet";

    &sub2;
    &sub3;
}

sub sub2
{
    print "\nName = $name\n";
}

sub sub3
{
    my $name = "Abhinav";
    print "\nName = $name\n";
}


&sub1;

Wyjście To:

Name = Abhishek

Name = Abhijeet

Name = Abhinav
 2
Author: Abhishek Kulkarni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-08 13:01:00

Przykład użycia przez Dinomite ' a lokalnego do redefiniowania ogranicznika rekordów to jedyny raz, na jaki natknąłem się w wielu programach Perla. Mieszkam w niszowym środowisku Perla [programowanie zabezpieczeń], ale tak naprawdę jest to rzadko używany zakres w moim doświadczeniu.

 0
Author: phreakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-01 16:01:16
&s;

sub s()
{
    local $s="5";
    &b;
    print $s;
}

sub b()
{
    $s++;
}

Powyższy skrypt wyświetla 6.

Ale jeśli zmienimy lokalny na mój to wydrukuje 5.

To jest różnica. Proste.
 0
Author: Peter Mortensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-13 18:55:33

Myślę, że najłatwiej zapamiętać to w ten sposób. MY tworzy nową zmienną. LOCAL tymczasowo zmienia wartość istniejącej zmiennej.

 0
Author: Hawk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-17 14:47:37