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

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

Ответ 1

Большой вопрос: как our отличается от my и что делает our?

В резюме:

Доступно с Perl 5, my - это способ объявить:

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


С другой стороны, переменными our являются:

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


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

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

Ответ 2

Ссылки PerlMonks и PerlDoc от Cartman и Olafur - отличная ссылка - ниже моя трещина в сводке:

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

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

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

Ответ 3

Пример:

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

Это старый вопрос, но я когда-либо встречал некоторые подводные камни о лексических объявлениях в 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. Помните функцию sort?

2. лексический или глобальный?

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

В C внешняя переменная является переменной, определенной вне любого функционального блока. С другой стороны, автоматическая переменная представляет собой переменную, определенную внутри функционального блока. Вот так:

int global;

int main(void) {
    int local;
}

В Perl все тонко:

sub main {
    $var = 42;
}

&main;

print "var: $var\n";

Вывод var: 42, $var - это глобальная переменная, даже определенная в функциональном блоке! Фактически в Perl любая переменная объявляется глобальной по умолчанию.

Урок состоит в том, чтобы всегда добавлять use strict; use warnings; в начале программы Perl, что заставит программиста явно объявлять лексическую переменную, так что мы не будем ошибаться в некоторых ошибках, принимаемых как должное.

Ответ 7

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

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

Ответ 8

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

#!/usr/bin/perl

our $foo = "BAR";

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

Вывод:

BAR
BAZ

Это не сработает, если вы измените "наш" на "мой".

Ответ 9

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" приведет к сбою при попытке запустить script:

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

Ответ 10

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

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

Ответ 11

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

Ответ 12

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

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

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

Источники: