В чем разница между моим и нашим в 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" (с именем ее пакета и двумя двоеточиями), и его лексическое псевдоним.
источники: