패키지 변수 대 어휘 변수를 언제 사용해야합니까 (그리고 차이점은 무엇입니까?)
문제
오래된 Perl 코드를보고 있습니다 평범한 승려 Win32 :: Ole 및 MS Word로 프로그래밍을 파악합니다. 코드 전체에 흩어져있는 이름과 같은 변수가 있습니다 $ ms :: Word 그리고 같은나의'그들의 선언에 포함. Google을 조금 읽은 후에는이를 사용하여 선언 된 '패키지 변수'대 '어휘 변수'라고합니다. 나의.
내 첫 번째 질문은 '패키지 변수는 무엇입니까?'. 나는 어휘 변수가 무엇인지 이해하지만 패키지 변수의 목적이나 그 사용이 어휘와 어떻게 다른지 이해하지 못하므로 두 번째 질문이 될 것입니다. '어휘와 패키지 변수의 차이점은 무엇입니까?'
해결책
패키지 변수는 기호 테이블에 거주하므로 이름이 주어지면 다른 패키지 나 범위에서 읽거나 수정할 수 있습니다. 어휘 변수의 범위는 프로그램 텍스트에 의해 결정됩니다. 그 영역 "내 ()를 통한 개인 변수" Perlsub에서 Manpage는 어휘 정의에 대한 자세한 내용을 제공합니다.
다음이 있다고 말합니다 MyModule.pm
:
package MyModule;
# these are package variables
our $Name;
$MyModule::calls = "I do not think it means what you think it means.";
# this is a lexical variable
my $calls = 0;
sub say_hello {
++$calls;
print "Hello, $Name!\n";
}
sub num_greetings {
$calls;
}
1;
패키지가 포함되어 있습니다 $calls
그리고 어휘 $calls
. 누구나 전자에게 갈 수 있지만 모듈은 후자에 대한 액세스를 제어합니다.
#! /usr/bin/perl
use warnings;
use strict;
use MyModule;
foreach my $name (qw/ Larry Curly Moe Shemp /) {
$MyModule::Name = $name;
MyModule::say_hello;
}
print MyModule::num_greetings, "\n";
print "calls = $MyModule::calls\n";
프로그램의 출력입니다
Hello, Larry!
Hello, Curly!
Hello, Moe!
Hello, Shemp!
4
calls = I do not think it means what you think it means.
보시다시피, 패키지 변수는 글로벌이므로 모든 일반적인 gotchas와 조언에 대한 조언은 적용됩니다. 명시 적으로 액세스를 제공하지 않는 한 MyModule 패키지 외부의 코드가 어휘에 액세스하는 것은 불가능합니다. $calls
.
경험의 규칙은 당신이 거의 항상 어휘를 사용하고 싶어한다는 것입니다. Perl 모범 사례 Damian Conway는 직접적입니다. "변수를 모듈의 인터페이스의 일부로 만들지 마십시오"(원본의 강조).
다른 팁
당신은 읽어야합니다 범위에 대처합니다 MJD에 의해.
Perldoc perlmod 유용한 독서도 있습니다.
이 코드는이 세상에서 추악합니다. 저자가 $ author :: email이 멋지다고 생각하기 때문에 세상에서 우려하지 않고 모든 종류의 네임 스페이스에 짓밟 힙니다.
더 나은 방법은 해시를 사용하는 것입니다.
my %author = (
email => 'author@example.com',
...
);
기호 테이블 전체에 트램핑이 필요하지 않습니다.
나는 몇 가지가있다 Win32::OLE
예 : http://www.unur.com/comp/ 예술 작품은 아니지만 나는이 스타일에 대한 개선이라고 생각합니다. 또한보십시오 Word 문서의 페이지 수가 Perl 및 Word VBA에서 다른 이유는 무엇입니까?
나는 조금 울려 줄 것이다:
@pgm::runtime_args = @ARGV ;
그래서 우리는 표준을 포기합니다 @ARGV
트래블에 배열 pgm
네임 스페이스. 뿐만 아니라 모든 Perl 프로그래머는 무엇을 알고 있습니다 @ARGV
이다. 어쨌든 @pgm::runtime_args
스크립트에서 다시 사용되지 않습니다.
$pgm::maxargs = $#pgm::runtime_args + 1 ;
물론 @pgm::runtime_args
스칼라 컨텍스트에서는 해당 배열의 요소 수를 제공합니다. 나는 이유를 모른다 $pgm::maxargs
필요할 수도 있지만 그렇다면이 라인은 다음과 같아야합니다.
$pgm::maxargs = @pgm::runtime_args;
나는이 물건을 더 많이 인용하지 않을 것입니다. COBOL 프로그래머가 Perl을 쓰려고 할 때 이것이 일어나는 일이라고 생각합니다.
$program::copyright = "Copyright (c) 02002 - Kenneth Tomiak : All rights reserved.";
나는 그가 올해 5 자리를 할당 한 것을 기쁘게 생각합니다. 나중에 몰라!
추신 : 내 발췌문이 공정한 사용을 구성한다고 생각합니다.
패키지 변수는 글로벌 변수입니다. 그들은 전체 프로그램 (다른 모듈)의 모든 곳에서 볼 수 있습니다. 그들은 당신이 그 수준의 가시성 및/또는 외부 영향을 원하거나 필요할 때 유용합니다. 예를 들어 텍스트 :: 랩 모듈은이를 사용하여 텍스트를 랩핑 할 열의 수에 대한 단일 구성 지점을 허용합니다. FUTHERMORE 패키지 변수를 사용하면 "Dynamic Scoping"이라는 것을 사용할 수 있지만 다소 고급스럽고 약간 난해한 개념입니다.
두 번째 질문은 참조하십시오 Perl에서 저와 우리의 차이점은 무엇입니까?