5

我正在查看Perl Monks上的一些较旧的 Perl 代码,以了解如何使用 Win32::OLE 和 MS Word 进行编程。分散在整个代码中的是名称如$MS::Word之类的变量,它们的声明中没有包含“ my ”。在 Google 上阅读了一下之后,我了解到这些被称为“包变量”与使用my .

我的第一个问题是'包变量有什么用?'。我(认为)我了解词法变量是什么,但我不了解包变量的用途或它们的使用与词法有何不同,所以我的第二个问题是,'词法变量和包变量有什么区别?'

4

3 回答 3

9

您应该阅读MJD 的Coping with Scoping

perldoc perlmod也将是有用的阅读。

代码太丑陋了。仅仅因为作者似乎认为 $author::email 很酷,它就践踏了各种各样的命名空间。

更好的方法是使用哈希:

my %author = (
   email => 'author@example.com',
   ...
);

没有必要遍历符号表。

我确实有一些Win32::OLE例子:http ://www.unur.com/comp/这不是艺术品,但我相信这是对这种风格的改进。另请参阅为什么在 Perl 和 Word VBA 中 Word 文档的页数不同?

我要吐槽一点

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

我很高兴他为这一年分配了五位数。你永远不知道!

PS:我相信我的摘录构成合理使用。

于 2009-06-19T19:31:57.417 回答
8

包变量存在于符号表中,因此根据其名称,可以从任何其他包或范围读取或修改它。词法变量的范围由程序文本决定。perlsub 联机帮助页中的“通过 my() 的私有变量”部分提供了有关定义词法的更多详细信息。

假设我们有以下内容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.

如您所见,包变量是全局变量,因此所有常见的问题和建议都反对 apply。除非明确提供访问权限,否则 MyModule 包之外的代码不可能访问其 lexical $calls

经验法则是你几乎总是想使用词汇。Damian Conway 的Perl Best Practices是直接的:“永远不要让变量成为模块接口的一部分”(强调原文)。

于 2009-06-19T20:10:11.613 回答
5

包变量是全局变量;它们在整个程序(甚至其他模块)中随处可见。当您想要或需要那种级别的可见性和/或外部影响时,它们很有用。例如,Text::Wrap 模块使用它们来允许单个配置点用于换行文本的列数。此外,包变量允许您使用称为“动态作用域”的东西——但这是一个有点高级且有点深奥的概念。

对于您的第二个问题,请参阅Perl 中的 my 和 our 有什么区别?

于 2009-06-19T19:25:53.390 回答