[perl] Perl에서 ‘나’와 ‘우리’의 차이점은 무엇입니까?

나는 myPerl에 무엇이 있는지 안다 . 정의 된 블록의 범위에만 존재하는 변수를 정의합니다. 무엇을 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.

예를 들어, 변수 $xinside의 정규화 된 이름 package main$main::x입니다. 선언은 our $x당신이 베어 사용할 수 있습니다 $x선언, 스크립트 사용의 범위에서, (그 결과의 오류없이, 즉) 위약금없이 변수를 use strictuse strict "vars". 범위는 하나 또는 둘 이상의 패키지 또는 하나의 작은 블록 일 수 있습니다.


답변

cartman과 Olafur의 PerlMonks와 PerlDoc 링크는 훌륭한 참고 자료입니다-아래는 요약에서 내 균열입니다.

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


답변

범위 지정에 대처 하는 것은 Perl 범위 지정 규칙에 대한 좋은 개요입니다. our본문에서 다루지 않을 정도로 오래 되었습니다. 끝에 있는 참고 섹션에서 설명합니다.

이 기사에서는 패키지 변수 및 동적 범위와 어휘 변수 및 어휘 범위와의 차이점에 대해 설명합니다.


답변

my지역 변수에 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에 사전 정의 된 전역 변수 이기 때문 입니다. 정렬 기능을 기억 하십니까?

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 프로그램의 시작 부분에 추가 하는 것입니다. 프로그래머는 어휘 변수를 명시 적으로 선언해야합니다.


답변

perldoc을은 우리의 좋은 정의를 가지고있다.

변수에 스토리지를 할당하고 현재 범위 내에서 사용하기 위해 간단한 이름을 해당 스토리지와 연관시키는 my와 달리, 현재 범위 내에서 사용하기 위해 단순 이름을 현재 패키지의 패키지 변수와 연관시킵니다. 다시 말해, 우리와 같은 범위 지정 규칙이 있지만 반드시 변수를 만들 필요는 없습니다.