문제

나는이 스크립트에 사용 된 두 가지를보고 있습니다. 나는 디버깅을 시도하고 있으며 문헌은 명확하지 않습니다. 누군가 나를 위해 이것을 탈취 할 수 있습니까?

도움이 되었습니까?

해결책

역동적 인 범위. 깔끔한 개념입니다. 많은 사람들이 그것을 사용하거나 이해하지 못합니다.

기본적으로 생각하십시오 my 변수를 {}의 한 블록, 일명 스코프로 만들고 고정시킵니다.

my $foo if (true); # $foo lives and dies within the if statement.

그래서 a my 변수는 당신이 익숙한 것입니다. 동적 범위를 사용하면 $ var는 어디서나 선언되어 어디에서나 사용할 수 있습니다. 그래서 local 기본적으로 해당 글로벌 변수의 사용을 중단하고 "로컬 값"을 사용하여 작업합니다. 그래서 local 임시 변수에 대한 임시 범위를 만듭니다.

$var = 4;
print $var, "\n";
&hello;
print $var, "\n";

# subroutines
sub hello {
     local $var = 10;
     print $var, "\n";
     &gogo; # calling subroutine gogo
     print $var, "\n";
}
sub gogo {
     $var ++;
}

이것은 인쇄해야합니다 :

4
10
11
4

다른 팁

짧은 대답은 그 것입니다 my 변수를 어휘 범위로 비공개로 표시하고 local 변수를 동적 범위에서 비공개로 표시합니다.

이해하기가 더 쉽습니다 my, 그것은 일반적인 의미에서 로컬 변수를 생성하기 때문에. 새로운 변수가 생성되며 일반적으로 곱슬 버팀대로 표시되는 동봉 된 어휘 블록 내에서만 액세스 할 수 있습니다. Curly-Brace 규칙에는 다음과 같은 몇 가지 예외가 있습니다.

foreach my $x (@foo) { print "$x\n"; }

그러나 그것은 단지 당신이 의미하는 바를하는 Perl입니다. 일반적으로 다음과 같은 것이 있습니다.

sub Foo {
   my $x = shift;

   print "$x\n";
}

이 경우 $x 서브 루틴에 비공개이며 그 범위는 곱슬 괄호로 둘러싸여 있습니다. 주목해야 할 것은 local, 그것이 a의 범위입니다 my 변수는 파일에 작성된 코드와 관련하여 정의됩니다. 컴파일 타임 현상입니다.

이해하다 local, 당신은 프로그램이 실행중인 것처럼 프로그램의 호출 스택 측면에서 생각해야합니다. 변수가있을 때 local, 그것은 local 문장을 포함하는 블록의 발신자에게 스택을 다시 반환 할 때까지 스택의 아래의 모든 것을 실행합니다. local.

이것은 처음에는 혼란 스러울 수 있으므로 다음 예를 고려하십시오.

sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }

$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect

언제 foo 처음이라고 불리는 것은 글로벌 가치를 본다. $x 1은 1입니다 bar 호출됩니다 local $x 실행됩니다. 글로벌을 재정의합니다 $x 스택에. 이제 언제 foo 호출됩니다 bar, 그것은 2의 새로운 값을 본다 $x. 지금까지는 그다지 특별하지 않습니다. local. 마법은 언제입니다 bar 반환 우리는 생성 된 동적 범위를 종료합니다 local $x 그리고 이전 글로벌 $x 스코프로 돌아옵니다. 그래서 마지막 전화를 위해 foo, $x 1입니다.

당신은 거의 항상 사용하기를 원할 것입니다 my, 그것은 당신이 찾고있는 로컬 변수를 제공하기 때문입니다. 한 번 파란 달에, local 멋진 일을하는 것이 정말 편리합니다.

인용 학습 perl:

그러나 지역의 이름은 잘못되거나 적어도 오해의 소지가 있습니다. 우리의 친구 Chip Salzenberg는 1986 년에 타임머신으로 돌아가서 Larry에게 한 가지 조언을 할 기회가 있다면 Larry에게 "Save"라는 이름으로 지역에 전화하라고 말할 것이라고 말했다. [14] 로컬은 실제로 주어진 글로벌 변수의 값을 절약 할 것이기 때문에 나중에 자동으로 글로벌 변수로 복원됩니다. (맞습니다 :이 소위 "로컬"변수는 실제로 글로벌입니다!)이 저장 및 레스트 메커니즘은 우리가 이미 두 번 보았던 것과 동일합니다. 서브 루틴 매개 변수 배열.

그래서, local 글로벌 변수의 현재 값을 저장 한 다음 어떤 형태의 빈 값으로 설정합니다. 종종 줄을 이끌지 않고 전체 파일을 비방하는 데 사용되는 것을 종종 볼 수 있습니다.

my $file_content;
{
    local $/;
    open IN, "foo.txt";
    $file_content = <IN>;
} 

부름 local $/ 입력 레코드 분리기 (Perl이 "line"at at을 중지하는 값)를 빈 값으로 설정하여 우주선 연산자가 전체 파일을 읽지 않으므로 입력 레코드 분리기에 부딪치지 않습니다.

나는 그 문제에 대한 Mark Jason Dominus의 철저한 논문과 관련이 없다고 믿을 수 없다.

http://perldoc.perl.org/perlsub.html#private-variables-via-my ()

현지 운영자가 생성 한 동적 변수와 달리, My와 함께 선언 된 어휘 변수는 서브 루틴이라는 이름을 포함하여 외부 세계에서 완전히 숨겨져 있습니다. 자체적으로 또는 다른 곳에서 호출 된 동일한 서브 루틴 인 경우에도 마찬가지입니다.

http://perldoc.perl.org/perlsub.html#temporary-values-via-local ()

로컬은 나열된 변수가 "로컬"으로 수정하여 블록, 평가 또는 수행 파일 및 해당 블록 내에서 호출 된 서브 루틴으로 수정합니다. 로컬은 글로벌 (의미 패키지) 변수에 임시 값을 제공합니다. 로컬 변수를 생성하지 않습니다. 이것은 동적 범위로 알려져 있습니다. 어휘 스코핑은 C의 자동 선언과 비슷하게 작동하는 My와 함께 이루어집니다.

나는 이것이 "공개 블록에 로컬"에 의해 블록이 종료 될 때 원래 값이 복원된다는 말을하는 것 외에는 이것이 불분명하다고 생각하지 않습니다.

글쎄, Google은 이것에 대해 정말로 당신에게 효과적입니다. http://www.perlmonks.org/?node_id=94007

링크에서 :

빠른 요약 : '내'새로운 변수를 만듭니다. 'local'은 일시적으로 변수의 값을 수정합니다.

즉, '로컬' 변수의 값을 일시적으로 변경합니다, 그러나만 범위 내에서 존재합니다.

일반적으로 내 사용은 더 빠르며 이상한 일을하지 않습니다.

에서 man perlsub:

현지 운영자가 생성 한 동적 변수와 달리, My와 함께 선언 된 어휘 변수는 서브 루틴이라는 이름을 포함하여 외부 세계에서 완전히 숨겨져 있습니다.

그래서 지나치게 단순화하고 my 변수가 선언 된 경우에만 가시적으로 만듭니다. local 통화 스택을 아래로 보이게합니다. 당신은 보통 사용하고 싶을 것입니다 my 대신에 local.

당신의 혼란은 이해할 수 있습니다. 어휘 스코핑은 이해하기 쉽지만 역동적 인 범위는 특이한 개념입니다. 상황은 이름으로 악화됩니다 my 그리고 local 역사적 이유로 다소 부정확 한 (또는 적어도 직관적이지 않은).

my 어휘 변수를 선언합니다 - 선언 시점에서 둘러싸는 블록 (또는 파일)의 끝까지 볼 수있는 변수가 나타납니다. 프로그램의 나머지 부분에서 동일한 이름을 가진 다른 변수와 완전히 독립적입니다. 그것은 그 블록에 비공개입니다.

local, 반면에, 글로벌 변수의 값에 대한 일시적인 변경을 선언합니다. 변경 사항은 동봉 범위의 끝에서 끝나지만 변수 (전역)는 프로그램의 어느 곳에서나 볼 수 있습니다.

경험상 사용하십시오 my 자신의 변수를 선언합니다 local Perl의 내장 변수에 대한 변경의 영향을 제어합니다.

보다 철저한 설명은 Mark Jason Dominus의 기사를 참조하십시오. 범위에 대처합니다.

local is an older method of localization, from the times when Perl had only dynamic scoping. Lexical scoping is much more natural for the programmer and much safer in many situations. my variables belong to the scope (block, package, or file) in which they are declared.

local variables instead actually belong to a global namespace. If you refer to a variable $x with local, you are actually referring to $main::x, which is a global variable. Contrary to what it's name implies, all local does is push a new value onto a stack of values for $main::x until the end of this block, at which time the old value will be restored. That's a useful feature in and of itself, but it's not a good way to have local variables for a host of reasons (think what happens when you have threads! and think what happens when you call a routine that genuinely wants to use a global that you have localized!). However, it was the only way to have variables that looked like local variables back in the bad old days before Perl 5. We're still stuck with it.

"my" variables are visible in the current code block only. "local" variables are also visible where ever they were visible before. For example, if you say "my $x;" and call a sub-function, it cannot see that variable $x. But if you say "local $/;" (to null out the value of the record separator) then you change the way reading from files works in any functions you call.

In practice, you almost always want "my", not "local".

Look at the following code and its output to understand the difference.

our $name = "Abhishek";

sub sub1
{
    print "\nName = $name\n";
    local $name = "Abhijeet";

    &sub2;
    &sub3;
}

sub sub2
{
    print "\nName = $name\n";
}

sub sub3
{
    my $name = "Abhinav";
    print "\nName = $name\n";
}


&sub1;

Output is :

Name = Abhishek

Name = Abhijeet

Name = Abhinav

dinomite's example of using local to redefine the record delimiter is the only time I have ran across in a lot of perl programming. I live in a niche perl environment [security programming], but it really is a rarely used scope in my experience.

&s;

sub s()
{
    local $s="5";
    &b;
    print $s;
}

sub b()
{
    $s++;
}

The above script prints 6.

But if we change local to my it will print 5.

This is the difference. Simple.

I think the easiest way to remember it is this way. MY creates a new variable. LOCAL temporarily changes the value of an existing variable.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top