В чем разница между моим и нашим в Perl?


Я знаю my Это в Perl. Он определяет переменную, которая существует только в области блока, в котором она определена. Что значит our сделать? Как это our отличается от my?

12 171

12 ответов:

Отличный вопрос: как это our отличается от my и что значит our делать?

В Итоге:

доступно с Perl 5,my - это способ заявить:

  • непакетные переменные, то есть
  • частные
  • новая,
  • неглобальных переменные
  • отдельно от любого пакета. Так что переменная не может доступ в виде $package_name::variable.


С другой стороны, our переменные:

  • переменные пакета, и таким образом автоматически
  • глобальные переменные
  • наверняка не рядовой,
  • и они не обязательно новые; и они
  • можете доступ вне пакета (или лексической области) с помощью квалифицированное пространство имен, как $package_name::variable.


объявление переменной с our позволяет предварительно вычислять переменные, чтобы использовать их под use strict без получения предупреждений опечатки или ошибок времени компиляции. Начиная С Perl 5.6, он заменил устаревшие use vars, который был только с файловой областью, а не с лексической областью, как это our.

например, формальное, полное имя переменной $x внутри package main и $main::x. Объявления our $x позволяет использовать голый $x переменная без штрафа (т. е. без результирующей ошибки), в области объявления, когда скрипт использует use strict или use strict "vars". Область действия может быть один, или два, или несколько пакетов, или один небольшой блок.

ссылки PerlMonks и PerlDoc от cartman и Olafur-отличная ссылка-ниже моя трещина в резюме:

my переменные лексически ограничены в пределах одного блока, определенного {} или в том же файле, если не в {}s. они недоступны из пакетов / подпрограмм, определенных вне одной и той же лексической области / блока.

our переменные находятся в пределах пакета / файла и доступны из любого кода, который use или require что конфликты между пакетами и именами файлов разрешаются путем добавления соответствующего пространства имен.

просто чтобы завершить его,local переменные имеют" динамическую " область видимости, отличающуюся от my переменные в том, что они также доступны из подпрограмм, вызываемых в том же блоке.

пример:

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";

борьба с обзора это хороший обзор правил определения области Perl. Он достаточно стар, чтобы our не обсуждается в тексте. Он обратился в Примечания раздел в конце.

в статье рассказывается о переменных пакета и динамической области и о том, как это отличается от лексических переменных и лексической области.

my используется для локальных переменных, где as our используется для глобальных переменных. Больше чтения над переменная область видимости в Perl: основы .

это старый вопрос, но я когда-либо встречал некоторые подводные камни о лексических декларациях в Perl, которые испортили меня, которые также связаны с этим вопросом, поэтому я просто добавляю свое резюме здесь:

1. определение или декларация?

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

выход var: 42. Однако мы не могли сказать, если local $var = 42; это определение или объявление. Но как насчет этого:

use strict;
use warnings;

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

вторая программа будет бросать ошибка:

Global symbol "$var" requires explicit package name.

$var не определено, что означает local $var; - это просто декларация! Перед использованием local чтобы объявить переменную, убедитесь, что она определена как глобальная переменная ранее.

но почему это не удастся?

use strict;
use warnings;

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

выход: var: 42.

потому что $a, а также $b, является глобальной переменной, предварительно определенной в Perl. Запомните вроде

The perldoc имеет хорошее определение нашего.

В отличие от my, который одновременно выделяет хранилище для переменной и связывает простое имя с этим хранилищем для использования в текущей области, Наше связывает простое имя с переменной пакета в текущем пакете для использования в текущей области. Другими словами, our имеет те же правила области видимости, что и my, но не обязательно создает переменную.

это только несколько связано с вопросом, но я только что обнаружил (для меня) неясный бит синтаксиса perl, который вы можете использовать с переменными "our" (package), которые вы не можете использовать с "моими" (локальными) переменными.

#!/usr/bin/perl

our $foo = "BAR";

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

выход:

BAR
BAZ

это не будет работать, если вы измените " наш " на "мой".

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";

выведет это:

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 

в случае использования "use strict" получит этот сбой при попытке запустить скрипт:

Global symbol "$test1" requires explicit package name at ./check_global.pl line 24.
Execution of ./check_global.pl aborted due to compilation errors.

просто попробуйте использовать следующую программу :

#!/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";
#!/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;

давайте подумаем, что такое интерпретатор на самом деле: это фрагмент кода, который хранит значения в памяти и позволяет инструкциям в программе, которую он интерпретирует, обращаться к этим значениям по их именам, которые указаны внутри этих инструкций. Таким образом, большая работа интерпретатора заключается в формировании правил того, как мы должны использовать имена в этих инструкциях для доступа к значениям, которые хранит интерпретатор.

при встрече с "my" интерпретатор создает лексическую переменную: a с именем значение, к которому интерпретатор может получить доступ только во время выполнения блока и только из этого синтаксического блока. При встрече с "нашим" интерпретатор создает лексический псевдоним переменной пакета: он связывает имя, которое интерпретатор должен с этого момента обрабатывать как имя лексической переменной, пока блок не будет завершен, со значением переменной пакета с тем же именем.

эффект заключается в том, что вы можете сделать вид, что вы используете лексическую переменную и обойти правила 'use strict' по полной квалификации пакетных переменных. Поскольку интерпретатор автоматически создает переменные пакета при их первом использовании, побочным эффектом использования "our" также может быть то, что интерпретатор также создает переменную пакета. В этом случае создаются две вещи: переменная пакета, к которой интерпретатор может получить доступ отовсюду, при условии, что она правильно обозначена в соответствии с запросом "use strict" (с добавлением имени ее пакета и двух двоеточий), и его лексическое псевдоним.

источники: