Jaka jest różnica między my A our w Perlu?

Wiem co my jest w Perlu. Definiuje zmienną, która istnieje tylko w zakresie bloku, w którym jest zdefiniowana. Co robi our? Czym our różni się od my?

 171

12 answers

[[18]}Wielkie pytanie: Jak our różnią się od my a co robi our zrobić?

W Podsumowaniu:

Dostępne od Perla 5, my jest sposobem deklarowania:

  • zmienne niepakowane, które są
  • prywatne,
  • Nowy ,
  • Nie-globalne zmienne,
  • oddzielnie od każdego opakowania. Aby zmienna Nie mogła być dostępne w formie $package_name::variable.


Z drugiej strony, our zmienne to:

  • zmienne pakietu, a więc automatycznie
  • globalne zmienne,
  • zdecydowanie Nie prywatny ,
  • [[39]}ani nie są one koniecznie nowe; i [40]}
  • Może być dostępna poza pakietem (lub zakresem leksykalnym) za pomocą kwalifikowana przestrzeń nazw, jako $package_name::variable.


Deklarowanie zmiennej z our pozwala na zapisywanie zmiennych w celu ich wykorzystania Pod use strict bez otrzymywania ostrzeżeń o błędach w czasie kompilacji. Od Perla 5.6 zastąpił on przestarzałe use vars, który miał tylko zasięg pliku, a nie zasięg leksykalny jak jest our.

Na przykład formalna, kwalifikowana nazwa zmiennej $x wewnątrz package main to $main::x. Deklarowanie our $x pozwala na użycie zmiennej bare $x bez kary (tzn. bez wynikowego błędu), w zakresie deklaracji, gdy skrypt używa use strict lub use strict "vars". Zakres może być jednym, dwoma lub więcej pakietami lub jednym małym blokiem.

 198
Author: Fran Corpier,
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-08-18 23:37:13

Linki Perlmonków i PerlDoc od Cartmana i Olafura są świetnym odniesieniem - poniżej jest moje podsumowanie:

my zmienne mają zasięg leksykalny w jednym bloku zdefiniowanym przez {} lub w tym samym pliku, jeśli nie w {}s. nie są dostępne z pakietów / podprogramów zdefiniowanych poza tym samym zakresem leksykalnym / blokiem.

our zmienne są skalowane w pakiecie/pliku i dostępne z dowolnego kodu use lub require, który konfliktuje nazwę pakietu / pliku rozwiązywane pomiędzy pakietami poprzez dodanie odpowiedniej przestrzeni nazw.

Aby to podsumować, local zmienne są" dynamicznie " skalowane, różniące się od zmiennych my tym, że są również dostępne z podprogramów wywołanych w tym samym bloku.

 59
Author: bubaker,
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
2013-12-06 08:02:30

Przykład:

use strict;

for (1 .. 2){
    # Both variables are lexically scoped to the block.
    our ($o);  # Belongs to 'main' package.
    my  ($m);  # Does not belong to a package.

    # The variables differ with respect to newness.
    $o ++;
    $m ++;
    print __PACKAGE__, " >> o=$o m=$m\n";  # $m is always 1.

    # The package has changed, but we still have direct,
    # unqualified access to both variables, because the
    # lexical scope has not changed.
    package Fubb;
    print __PACKAGE__, " >> o=$o m=$m\n";
}

# The our() and my() variables differ with respect to privacy.
# We can still access the variable declared with our(), provided
# that we fully qualify its name, but the variable declared
# with my() is unavailable.
print __PACKAGE__, " >> main::o=$main::o\n";  # 2
print __PACKAGE__, " >> main::m=$main::m\n";  # Undefined.

# Attempts to access the variables directly won't compile.
# print __PACKAGE__, " >> o=$o\n";
# print __PACKAGE__, " >> m=$m\n";

# Variables declared with use vars() are like those declared
# with our(): belong to a package; not private; and not new.
# However, their scoping is package-based rather than lexical.
for (1 .. 9){
    use vars qw($uv);
    $uv ++;
}

# Even though we are outside the lexical scope where the
# use vars() variable was declared, we have direct access
# because the package has not changed.
print __PACKAGE__, " >> uv=$uv\n";

# And we can access it from another package.
package Bubb;
print __PACKAGE__, " >> main::uv=$main::uv\n";
 45
Author: FMc,
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
2016-08-28 03:24:36

Radzenie sobie z przeszukiwaniem jest dobrym przeglądem reguł przeszukiwania Perla. Jest na tyle stary, że our nie jest omawiany w treści tekstu. Jest on omówiony w sekcji Uwagi na końcu.

Artykuł mówi o zmiennych pakietowych i zakresie dynamicznym oraz o tym, jak różni się to od zmiennych leksykalnych i zakresu leksykalnego.

 12
Author: daotoad,
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-05-10 16:37:42

My jest używany dla zmiennych lokalnych, gdzie as our jest używany dla zmiennych globalnych. Więcej informacji na temat zmiennego zakresu w Perlu: podstawy .

 6
Author: ismail,
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-05-10 10:27:50

To stare pytanie, ale spotkałem się kiedyś z pewnymi pułapkami dotyczącymi deklaracji leksykalnych w Perlu, które mnie namieszały, które również są związane z tym pytaniem, więc po prostu dodaję moje podsumowanie tutaj: {]}

1. definicja czy deklaracja?

local $var = 42; 
print "var: $var\n"; 

Wyjście to var: 42. Nie mogliśmy jednak stwierdzić, czy local $var = 42; jest definicją czy deklaracją. Ale co powiesz na to:

use strict;
use warnings;

local $var = 42;
print "var: $var\n";

Drugi program wyrzuci błąd:

Global symbol "$var" requires explicit package name.

$var nie jest zdefiniowana, co oznacza, że local $var; jest tylko deklaracja! Przed użyciem local do zadeklarowania zmiennej upewnij się, że jest ona wcześniej zdefiniowana jako zmienna globalna.

Ale dlaczego to nie zawiedzie?

use strict;
use warnings;

local $a = 42;
print "var: $a\n";

Wyjście to: var: 42.

To dlatego, że $a, podobnie jak $b, jest zmienną globalną predefiniowaną w Perlu. Zapamiętaj sortowanie funkcja?

2. leksykalne czy globalne?

Byłem programistą C zanim zacząłem używać Perla, więc pojęcie zmiennych leksykalnych i globalnych wydaje się proste dla mnie: po prostu odpowiada auto i zmiennych zewnętrznych 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 jest zmienną zdefiniowaną wewnątrz bloku funkcyjnego. Tak:

int global;

int main(void) {
    int local;
}

Podczas gdy w Perlu, rzeczy są subtelne:

sub main {
    $var = 42;
}

&main;

print "var: $var\n";

Wyjście jest var: 42, $var jest zmienną globalną, nawet jeśli jest zdefiniowana w bloku funkcyjnym! Właściwie w Perlu każda zmienna jest domyślnie deklarowana jako globalna.

Lekcją jest zawsze dodawanie use strict; use warnings; na początku programu Perla, co zmusi programistę do jawnego zadeklarowania zmiennej leksykalnej, abyśmy nie dali się namieszać przez pewne błędy uznane za oczywiste.

 4
Author: Xu Ding,
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
2013-11-07 15:31:02

Perldoc ma dobrą definicję naszego

W przeciwieństwie do my, który przydziela pamięć dla zmiennej i kojarzy prostą nazwę z tą pamięcią do użycia w bieżącym zakresie, nasz kojarzy prostą nazwę ze zmienną pakietu w bieżącym pakiecie, do użycia w bieżącym zakresie. Innymi słowy, nasz ma te same zasady zakresów co my, ale niekoniecznie tworzy zmienną.

 3
Author: Ólafur Waage,
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-05-11 00:23:17

Jest to tylko w pewnym sensie związane z pytaniem, ale właśnie odkryłem (dla mnie) niejasny fragment składni Perla, którego możesz używać ze zmiennymi "our" (package), których nie możesz używać ze zmiennymi "my" (local).

#!/usr/bin/perl

our $foo = "BAR";

print $foo . "\n";
${"foo"} = "BAZ";
print $foo . "\n";

Wyjście:

BAR
BAZ
To nie zadziała, jeśli zmienisz 'Nasze ' na'moje'.
 2
Author: Misha Gale,
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
2011-12-02 15:03:03
print "package is: " . __PACKAGE__ . "\n";
our $test = 1;
print "trying to print global var from main package: $test\n";

package Changed;

{
        my $test = 10;
        my $test1 = 11;
        print "trying to print local vars from a closed block: $test, $test1\n";
}

&Check_global;

sub Check_global {
        print "trying to print global var from a function: $test\n";
}
print "package is: " . __PACKAGE__ . "\n";
print "trying to print global var outside the func and from \"Changed\" package:     $test\n";
print "trying to print local var outside the block $test1\n";

Wyświetli to:

package is: main
trying to print global var from main package: 1
trying to print local vars from a closed block: 10, 11
trying to print global var from a function: 1
package is: Changed
trying to print global var outside the func and from "Changed" package: 1
trying to print local var outside the block 

W przypadku, gdy użycie "use strict"spowoduje błąd podczas próby uruchomienia skryptu:

Global symbol "$test1" requires explicit package name at ./check_global.pl line 24.
Execution of ./check_global.pl aborted due to compilation errors.
 0
Author: Lavi Buchnik,
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-05 20:32:42

Po prostu spróbuj użyć następującego programu:

#!/usr/local/bin/perl
use feature ':5.10';
#use warnings;
package a;
{
my $b = 100;
our $a = 10;


print "$a \n";
print "$b \n";
}

package b;

#my $b = 200;
#our $a = 20 ;

print "in package b value of  my b $a::b \n";
print "in package b value of our a  $a::a \n";
 0
Author: Yugdev,
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-11-05 11:08:47
#!/usr/bin/perl -l

use strict;

# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'

our $lol = eval {$lol} || 'lol' ;

print $lol;
 -1
Author: xoid,
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
2013-05-16 08:02:24

Zastanówmy się, czym jest interpreter: jest to fragment kodu, który przechowuje wartości w pamięci i pozwala instrukcjom w programie, który interpretuje, uzyskać dostęp do tych wartości po ich nazwach, które są określone w tych instrukcjach. Tak więc wielkim zadaniem interpretera 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 interpretera.

Po napotkaniu" my " interpreter tworzy zmienną leksykalną: nazwaną wartość, która interpreter może uzyskać dostęp tylko podczas wykonywania bloku i tylko z wewnątrz tego bloku składniowego. Po napotkaniu "our", interpreter tworzy leksykalny alias zmiennej pakietu: wiąże nazwę, którą interpreter ma odtąd przetwarzać jako nazwę zmiennej leksykalnej, aż do zakończenia bloku, z wartością zmiennej pakietu o tej samej nazwie.

Efekt jest taki, że możesz wtedy udawać, że używasz zmiennej leksykalnej i ominąć zasady ' use strict " na pełną kwalifikację zmiennych pakietu. Ponieważ interpreter automatycznie tworzy zmienne pakietu podczas ich pierwszego użycia, efektem ubocznym użycia "our" 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 ona odpowiednio oznaczona przez 'use strict' (poprzedzona nazwą pakietu i dwoma dwukropkami), i jej leksykalna alias.

Źródła:

 -1
Author: Evgeniy,
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
2016-01-27 04:57:43