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

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

12 ответов


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

В Итоге:

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

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


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

  • переменные пакета, и таким образом автоматически
  • глобальные переменные
  • наверняка не рядовой,
  • и они не обязательно новые; и они
  • can доступ за пределами пакета (или лексической области) с помощью квалифицированное пространство имен, как $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";

справляться с Scoping - хороший обзор правил области 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. Помните вроде


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

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


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

#!/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 " интерпретатор создает лексическую переменную: именованную значение, к которому интерпретатор может получить доступ только при выполнении блока и только из этого синтаксического блока. При встрече с" нашим " интерпретатор делает лексический псевдоним переменной пакета: он связывает имя, которое интерпретатор должен отныне обрабатывать как имя лексической переменной, пока блок не будет завершен, со значением переменной пакета с тем же именем.

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

источники: