2014-02-18 2 views
0

필자는 Perl을 처음 사용하여 서브 루틴에 대한 이해를 돕고 싶습니다. 서브 루틴에서는 일부 변수가 항상 정의되지 않는 경우입니까? 서브 루틴의 변수가 비공개이기 때문에입니까? 그래서 이전에 정의되지 않은 변수를 정의하고자한다면 어떻게해야할까요? 미리 감사드립니다.펄 서브 루틴에서 정의되지 않은 변수

+0

http://perldoc.perl.org/perlintro.html을 검토하여 질문에 답하고 perl 프로그래밍에 대한 유용한 통찰력을 제공합니다. – Gabs00

답변

4

Perl의 변수는 비공개가 아니지만 범위가 제한 될 수 있습니다. 서브 루틴 안에 my으로 선언 할 때와 같습니다. 서브 루틴에 대한 인수는 변수 @_에 저장됩니다.

do_stuff($foo, $bar); 

sub do_stuff { 
    my ($first, $second) = @_; # direct assignment 
    print "First: $first, Second: $second\n"; 
} 

my 선언 어휘들은 보호 수단 주변 블록 { ... }에 범위 변수를 만들고, 실행 블록을 떠날 때 그들은 범위 밖으로 이동.

sub do_stuff { 
    my $first = shift; 
    my $second) = shift;  

이 그것도 @_로부터 요소를 제거하는 것을 제외하고, 동일한 일을 수행 서브 루틴

인수는 일반적 펄 코드에서 보여지는 배열 함수 shiftpop으로 액세스 할 수있는 정렬.

더 읽기 :

1

일반적으로 변수는 my 명령으로 정의됩니다 (기술적으로는 우리와 로컬 같은 다른 것들도 있지만 결코 사용하지 않습니다). 서브 루틴에서이 작업을 수행하는 경우

my $variable 

는 당신이 필요로하는 변수를 만들 것입니다 :

는 변수 유형을 정의합니다. 그 종종 좋은 생각이 코드에서 엄격한 지침을 사용 :

use strict 

이것은 당신에게 당신이 일을 정의 할 수 잊고 몇 가지 경고를 줄 것이다.

+2

'my $ variable'은 "변수 유형을 정의하지 않습니다." 변수를 선언합니다. – ikegami

2

이 변수가 범위 글로벌 있습니다. 즉, 스크립트의 끝 부분에서 스크립트를 정의한 곳에서 프로그램에 존재합니다. 또한 Perl에서는 변수를 정의되지 않은 값으로 사용할 때 변수가 존재하게됩니다. 문자열에서는 null 문자열로 처리됩니다. 숫자에서는 0으로 처리됩니다. 당신이 당신의 메인 프로그램에서 변수를 정의하는 경우

따라서, 서브 루틴, 그것은 당신의 서브 루틴에 정의되어 :

$foo = "Hello"; 
call_sub(); 

sub call_sub { 
    print "$foo\n"; 
} 

"안녕하세요"인쇄 할 것이다. 너무 쉽기 때문

그러나 아무도 오류가이 모드에서 펄을 사용하지해야합니다

$name = "Bob" 
print "Hello $Name!\n"; 

으악를! 내가 정의했을 때 $name을 사용했고, 그것을 사용할 때 $Name을 사용했습니다. 게다가, 당신은 그런 전역 변수를 원하지 않습니다.그렇지 않으면 서브 루틴이 주 프로그램 변수를 덮어 쓸 수 있습니다. 복잡한 프로그램을 작성하는 것은 정말 어렵습니다.

이 문제를 얻기 위해

는, 당신은 높은 코드에서이 두 줄을 넣어하는 것이 좋습니다 :

use strict; 
use warnings; 

use warnings;는 uninitialzed 변수는 문자열과 숫자로 취급되는 것으로 경고의 다양한 발급합니다 .

use strict;은 더 큰 변화를 가져옵니다. 단순히 (그리고 잘못) 넣으려면 use strict을 사용하기 전에 변수를으로 선언해야합니다.

use warnings; 
use strict; 

my $name = "Bob" 
print "Hello $Name\n"; 

$Name가 (당신이 my 키워드 변수를 선언) 선언되지 않았기 때문에이 프로그램은 작동하지 않습니다. 오류를 방지하는 방법을 알 수 있습니다.

그러나 이러한 변수 유형을 선언하는 것은 어휘적으로 범위의 변수로 알려져 있습니다. 즉, 그들은 존재하거나 존재하지 않을 수 있습니다. 변수가 블록에 정의 된 경우 블록 외부에서 정의되지 않습니다. 중괄호로 블록 생각해

서브 루틴은 서브 루틴에서 변수를 정의 할 경우 의미 블록

sub foo { # Curly brace starts the block 
    ... 
}   # Curly brace ends the block 

, 그것은 단지 그 서브 루틴입니다.

또한, whilefor 루프 블록입니다 :

for my $foo (@foo_list) { # The variable $foo is only defined in this loop 
    ... 
}        # End of block and end of loop 

while (my $foo = <@foo_list>) { # Again, $foo is only in this block 
    ... 
}         # End of the block 

if ($foo == $bar) {  # Another block 
    my $foo = 1;    # $foo is defined in the block 
}        # $foo is no longer defined 
심지어 단지 중괄호를 사용할 수 있습니다

: 당신이 할 수

my $foo = 2; 
my $bar = 5; 
print "$foo\n";    # Prints 2 
call_sub(5);     # Prints "Foo is 5!" 
print $foo\n";    # Prints 2 

sub call_sub { 
    my $foo = shift;   # Different $foo from main program! 
    print "Foo is $foo!\n"; 
    print "Bar is $bar\n"; # Will print "Bar is 5" because $bar is in scope 
}       # Subroutine's $foo falls out of scope 

:

my $foo = 1; 
print "$foo\n"    # Prints 1 
{ 
    my $foo = 2;    # Redefines $foo it's a different $foo! 
    print "$foo\n"   # Prints 2 
}        # End of block, $foo in block is now out of scope 
print "$foo\n";    # Prints 1 because the original $foo is in scope. 

이의이 보자 참조, 서브 루틴을 호출하기 전에 $bar을 정의했다. d이므로 서브 루틴에 정의되어 있고 여전히 범위 내에 있습니다. 그러나 내 서브 루틴의 $foo은 다시 선언되었고 서브 루틴이 끝날 때까지 남아서 범위를 벗어납니다. 따라서, 서브 루틴 $foo의 사용은 내 주요 프로그램을 방해하지 않습니다.

따라서, 귀하의 질문에 대답 :

  • 항상 use strict;를 사용합니다. 이렇게하면 변수를 사용하기 전에 변수를 선언하게됩니다.
  • 변수는 my으로 선언 될 때까지 정의되지 않습니다.
  • 변수는 살고 숨을 쉴 수있는 범위가 제한 될 수 있습니다. 이것은 매우 유용 할 수 있습니다. 거기에 앉아서 Pascal에서와 같이 프로그램 시작시 모든 변수를 my으로 선언하지 마십시오. 사용 장소를 선언하고 필요하지 않을 때 범위를 벗어나게하십시오.
  • 서브 루틴이 이미 선언 된 변수를 사용할 수 있기 때문에 서브 루틴 변수가 개인이 아닙니다. 이것은 이라는 나쁜 생각입니다. 서브 루틴이 주 프로그램의 변수 값을 무시할 수 있기 때문입니다. 따라서 항상 안전을 위해 서브 루틴 변수 my을 모두 선언하십시오.
  • use warnings;을 사용하면 사용하려고하는 변수를 정의하는 것을 잊었을 때 경고 할 수 있습니다.

그리고 마지막으로, 나는하지만 아주 좋은 이유, 거짓말. Perl의 변수는 내가 제시 한 것보다 훨씬 더 복잡합니다. 이라는 개념이 있고, 패키지 변수 및 로컬 화하는 방법은 변수가 로컬이 아니어도됩니다. Perl과 수년간 함께 일하는 사람들조차도 파급 효과를 이해하는 데 어려움이 있습니다.

use strict; 실제로 변수를 선언하지 않아도됩니다. 이것은 my으로 선언 한 어휘 적으로 범위가 지정된 변수를 사용하거나 패키지의 정규화 된 변수 이름을 사용하여 변수를 으로 사용하거나 해당 변수를 선언 할 때 사용합니다.

그러나 결국 use strict;은 Perl에서 사용할 변수의 99 %가 my으로 선언되므로 변수를 선언해야합니다. 펄에 대해 더 많이 배울 때, 다른 1 %에 대해 좀 더 배울 수 있습니다.

내가 어떻게 잊을 수 (자세한 내용은 private 변수에 대한 my 사용에 대한 PerlSub에서 살펴 및 전체 토론 PerlMod에 대한 패키지 변수 좀 봐, 지역 사용하고 !) 새로 도입 된 상태는입니다.