패키지 변수 대 어휘 변수를 언제 사용해야합니까 (그리고 차이점은 무엇입니까?)

StackOverflow https://stackoverflow.com/questions/1019617

문제

오래된 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에서 저와 우리의 차이점은 무엇입니까?

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