답변:
좋은 질문 : 어떻게 our
다를 my
무엇을 않습니다 our
합니까?
요약해서 말하자면:
Perl 5부터 사용 가능 my
하며 패키지가 아닌 변수를 선언하는 방법은 다음과 같습니다.
$package_name::variable
.반면에 our
변수는 패키지 변수이므로 자동으로 다음과 같습니다.
$package_name::variable
.변수 선언 our
을 사용하면 use strict
오타 경고 나 컴파일 타임 오류없이 변수를 사용하기 위해 변수를 미리 선언 할 수 있습니다. Perl 5.6부터는 use vars
파일 범위 만 있고 어휘 범위가 없는 구식을 대체했습니다 our
.
예를 들어, 변수 $x
inside의 정규화 된 이름 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
.
cartman과 Olafur의 PerlMonks와 PerlDoc 링크는 훌륭한 참고 자료입니다-아래는 요약에서 내 균열입니다.
my
변수는 s에 {}
있지 않은 경우 동일한 파일에 의해 정의 되거나 동일한 파일 내에 정의 된 단일 블록 내에서 어휘 범위가 지정됩니다 {}
. 동일한 어휘 범위 / 블록 외부에 정의 된 패키지 / 서브 루틴에서는 액세스 할 수 없습니다.
our
변수는 패키지 / 파일 내에서 범위가 지정 되며 적절한 네임 스페이스를 앞에 추가하여 패키지간에 use
또는 require
패키지 / 파일 이름 충돌이 해결 되는 모든 코드에서 액세스 할 수 있습니다 .
반올림하기 위해 local
변수는 "동적"범위를 가지며 my
동일한 블록 내에서 호출되는 서브 루틴에서도 액세스 할 수 있다는 점 에서 변수와 다릅니다 .
my
변수가 {}
s에 있지 않으면 같은 파일 내에서 어휘 범위 [...]로 +1 "입니다. 저에게 도움이되었습니다. 감사합니다.
예를 들면 :
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";
my
지역 변수에 our
사용되는 반면 전역 변수에 사용됩니다.
Perl의 변수 범위 지정에 대한 추가 정보 : 기본 사항 .
${^Potato}
글로벌입니다. 사용 위치에 관계없이 동일한 변수를 나타냅니다.
나는 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에 사전 정의 된 전역 변수 이기 때문 입니다. 정렬 기능을 기억 하십니까?
2. 어휘 또는 글로벌?
나는 Perl을 사용하기 전에 C 프로그래머 였기 때문에 어휘 및 전역 변수의 개념은 나에게 간단 해 보인다. 그것은 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 프로그램의 시작 부분에 추가 하는 것입니다. 프로그래머는 어휘 변수를 명시 적으로 선언해야합니다.
이것은 질문과 다소 관련이 있지만, "my"(로컬)와 함께 사용할 수없는 "our"(패키지) 변수와 함께 사용할 수있는 펄 구문의 모호한 비트를 발견했습니다. 변수.
#!/usr/bin/perl
our $foo = "BAR";
print $foo . "\n";
${"foo"} = "BAZ";
print $foo . "\n";
산출:
BAR
BAZ
'our'를 'my'로 변경하면 작동하지 않습니다.
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
출력 : barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
출력 : barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
출력 : barbar
테스트에서 같은 함정에 빠졌습니다. $ {foo}는 $ foo와 동일하며, 대괄호는 보간 할 때 유용합니다. $ { "foo"}는 실제로 기본 기호 테이블 인 $ main :: {}까지입니다. 패키지 범위 변수 만 포함합니다.
perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
이 컨텍스트 $ { "foo는"}과 같이 일 현재 $ { "테스트 :: foo는"}와 같습니다. 심벌 테이블과 글로브 에 대한 정보는 Advanced Perl 프로그래밍 서적과 같습니다. 이전 실수로 죄송합니다.
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
"엄격한 사용"을 사용하면 스크립트를 실행하는 동안이 오류가 발생합니다.
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;
our
와 my
의 차이점은 무엇입니까? 이 예는 어떻게 보여줍니까?
인터프리터가 실제로 무엇인지 생각해 보자. 메모리에 값을 저장하고 해석하는 프로그램의 명령이 이름으로 이러한 값에 액세스 할 수 있도록하는 명령이다. 따라서 통역사의 큰 임무는 통역사가 저장하는 값에 액세스하기 위해 해당 지시 사항의 이름을 사용하는 방법에 대한 규칙을 형성하는 것입니다.
"my"가 발생하면 인터프리터는 어휘 변수를 작성합니다. 인터프리터는 블록을 실행하는 동안에 만 해당 구문 블록 내에서만 액세스 할 수있는 명명 된 값입니다. "우리"를 만나면 인터프리터는 패키지 변수의 어휘 별명을 만듭니다. 인터프리터는 그 이후부터 블록이 완료 될 때까지 어휘 변수의 이름으로 처리하기 위해 인터프리터가 이름을 바인드하여 패키지의 값으로 바꿉니다. 같은 이름의 변수.
그 결과 어휘 변수를 사용하는 것처럼 가장하고 패키지 변수의 정규화에 대해 '엄격한 사용'규칙을 무시할 수 있습니다. 인터프리터는 패키지 변수가 처음 사용될 때 자동으로 패키지 변수를 작성하므로 "우리"를 사용하면 부작용으로 인해 패키지 변수도 작성 될 수 있습니다. 이 경우, 두 가지가 생성됩니다 : 패키지 변수, 인터프리터가 액세스 할 수 사방에서, (그 패키지와 두 개의 콜론의 이름 앞에 추가) '엄격한 사용'의 요청에 따라 제대로 지정된 것 제공 및 사전 적 별명.
출처 :