Я знаю, что my
есть в Perl. Он определяет переменную, которая существует только в области действия блока, в котором она определена. Что делает our
?
Чем our
отличается от my
?
Большой вопрос: чем 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"
. Область действия может быть одним, двумя или несколькими пакетами или одним небольшим блоком.
local
не создает переменных. Это не относитсяmy
иour
вообще.local
временно создает резервную копию значения переменной и очищает ее текущее значение.our
переменные не являются пакетными переменными. Они не глобальные, а переменные лексического масштаба, какmy
переменные. Вы можете видеть , что в следующей программе:package Foo; our $x = 123; package Bar; say $x;
. Если вы хотите «объявить» переменную пакета, вам нужно использоватьuse vars qw( $x );
.our $x;
объявляет переменную с лексической областью, которая связывается с переменной с тем же именем в пакете, в котором онаour
была скомпилирована.Ссылки PerlMonks и PerlDoc от Cartman и Olafur являются отличным справочным материалом. Ниже приведена моя краткая сводка:
my
переменные лексически ограничены в пределах одного блока, определенного{}
или внутри одного и того же файла, если не в{}
s. Они не доступны из пакетов / подпрограмм, определенных вне одной лексической области видимости / блока.our
переменные в области видимости пакета / файл и доступны из любого кода,use
илиrequire
что пакет / файл - конфликты имен разрешаются между пакетами, предваряя соответствующее пространство имен.Просто для округления,
local
переменные «динамически» ограничены, отличаясь отmy
переменных тем, что они также доступны из подпрограмм, вызываемых в одном и том же блоке.источник
my
переменных лексически ограничены [...] в одном и том же файле, если не в{}
s". Это было полезно для меня, спасибо.Пример:
источник
Справиться со Scoping - хороший обзор правил Perl. Это достаточно старое, что
our
не обсуждается в основной части текста. Он рассматривается в разделе « Примечания » в конце.В статье рассказывается о переменных пакета и динамической области видимости, а также о том, чем они отличаются от лексических переменных и лексической области видимости.
источник
my
используется для локальных переменных, тогдаour
как используется для глобальных переменных.Подробнее читайте в Variable Scoping в Perl: основы .
источник
${^Potato}
является глобальным. Он ссылается на одну и ту же переменную независимо от того, где вы ее используете.Я когда-либо встречал некоторые подводные камни в лексических декларациях в Perl, которые меня расстроили, которые также связаны с этим вопросом, поэтому я просто добавлю свое резюме здесь:
1. Определение или декларация?
Выход есть
var: 42
. Однако мы не могли сказать,local $var = 42;
является ли это определение или декларация. Но как насчет этого:Вторая программа выдаст ошибку:
$var
не определено, что означаетlocal $var;
просто объявление! Прежде чем использоватьlocal
для объявления переменной, убедитесь, что она определена как глобальная переменная ранее.Но почему это не подведет?
Выход:
var: 42
.Это потому
$a
, что$b
глобальная переменная предопределена в Perl. Помните функцию сортировки ?2. Лексический или глобальный?
Я был программистом на C до того, как начал использовать Perl, поэтому концепция лексических и глобальных переменных кажется мне простой: она просто соответствует auto и внешним переменным в C. Но есть небольшие различия:
В C внешняя переменная - это переменная, определенная вне любого функционального блока. С другой стороны, автоматическая переменная - это переменная, определенная внутри функционального блока. Как это:
В Perl все тонко:
Выход есть
var: 42
.$var
является глобальной переменной, даже если она определена в функциональном блоке! На самом деле в Perl любая переменная объявляется как глобальная по умолчанию.Урок состоит в том, чтобы всегда добавлять
use strict; use warnings;
в начале Perl-программу, что заставит программиста явно объявлять лексическую переменную, чтобы мы не ошиблись из-за некоторых ошибок, принимаемых как должное.источник
У perldoc есть хорошее определение нашего.
источник
Это только отчасти связано с вопросом, но я только что обнаружил (для меня) непонятный бит синтаксиса perl, который вы можете использовать с «нашими» (пакетными) переменными, которые вы не можете использовать с «моим» (локальным) переменные.
Вывод:
Это не сработает, если вы измените «наш» на «мой».
источник
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
output:barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
output:barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
output:barbar
Таким образом, в моем тестировании я попал в ту же ловушку. $ {foo} аналогично $ foo, скобки полезны при интерполяции. $ {"foo"} на самом деле выглядит как $ main :: {}, который является главной таблицей символов, так как он содержит только переменные области видимости пакета.perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
работам, так как в этом контексте $ {"foo"} теперь равно $ {"test :: foo"}. О символьных таблицах и глобусах есть некоторая информация об этом, как и книга по программированию на Advanced Perl. Извините за мою предыдущую ошибку.Будет выводить это:
В случае использования «use strict» вы получите этот сбой при попытке запустить скрипт:
источник
Просто попробуйте использовать следующую программу:
источник
источник
our
иmy
разные? Как этот пример показывает это?Давайте подумаем, что такое интерпретатор на самом деле: это кусок кода, который хранит значения в памяти и позволяет командам в программе, которые он интерпретирует, получать доступ к этим значениям по их именам, которые указаны внутри этих инструкций. Таким образом, большая задача интерпретатора состоит в том, чтобы сформировать правила использования имен в этих инструкциях для доступа к значениям, которые хранит интерпретатор.
При обнаружении «my» интерпретатор создает лексическую переменную: именованное значение, к которому интерпретатор может получить доступ только во время выполнения блока и только из этого синтаксического блока. При обнаружении «нашего» интерпретатор создает лексический псевдоним переменной пакета: он связывает имя, которое интерпретатор должен с тех пор обрабатывать как имя лексической переменной, пока блок не будет завершен, со значением пакета. переменная с тем же именем.
В результате вы можете притворяться, что используете лексическую переменную, и обходить правила «строгого использования» при полной квалификации переменных пакета. Поскольку интерпретатор автоматически создает переменные пакета при их первом использовании, побочным эффектом использования «нашего» также может быть то, что интерпретатор также создает переменную пакета. В этом случае создаются две вещи: переменная пакета, к которой интерпретатор может получить доступ отовсюду, при условии, что она правильно обозначена в соответствии с запросом 'use strict' (с добавлением имени ее пакета и двух двоеточий) и ее лексическим псевдонимом.
Источники:
источник