rom*_*das 5 variables perl scope package lexical
我在Perl Monks上查看一些较旧的Perl代码,以找出使用Win32 :: OLE和MS Word编程.整个代码中分散的是名为$ MS :: Word之类的变量,其声明中没有包含" my ".在Google上阅读了一下之后,我明白这些被称为"包变量"与使用我的声明的"词汇变量" .
我的第一个问题是' 什么是包变量有用?".我(想)我理解词汇变量是什么,但我不明白包变量的目的或它们的用法与词汇有何不同,所以我的第二个问题是,' 词法和包变量有什么区别?"
您应该阅读MJD的应对范围.
perldoc perlmod也很有用.
代码离这个世界很难看.它仅仅因为作者似乎认为$ author :: email很酷而践踏各种命名空间而不用担心.
更好的方法是使用哈希:
my %author = (
email => 'author@example.com',
...
);
Run Code Online (Sandbox Code Playgroud)
践踏符号表不是必需的.
我有几个Win32::OLE例子:http://www.unur.com/comp/这些都不是艺术品,但我相信这种风格有所改进.另请参阅为什么Word文档中的页数在Perl和Word VBA中有所不同?
我要咆哮一下:
@pgm::runtime_args = @ARGV ;
Run Code Online (Sandbox Code Playgroud)
因此,我们放弃了标准@ARGV数组来践踏pgm命名空间.不仅如此,每个Perl程序员都知道它是什么@ARGV.无论如何,@pgm::runtime_args脚本中不再使用.
$pgm::maxargs = $#pgm::runtime_args + 1 ;
Run Code Online (Sandbox Code Playgroud)
当然,@pgm::runtime_args在标量上下文中将为我们提供该数组中元素的数量.我不知道为什么$pgm::maxargs可能需要,但如果是,那么这一行应该是:
$pgm::maxargs = @pgm::runtime_args;
Run Code Online (Sandbox Code Playgroud)
我不会引用更多这些东西.我猜这是Cobol程序员尝试编写Perl时会发生的事情.
$program::copyright = "Copyright (c) 02002 - Kenneth Tomiak : All rights reserved.";
Run Code Online (Sandbox Code Playgroud)
我很高兴他今年分配了五位数.雅永远不知道!
PS:我相信我的摘录是合理使用的.
包变量存在于符号表中,因此根据其名称,可以从任何其他包或范围中读取或修改它.词汇变量的范围由程序文本确定.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;
Run Code Online (Sandbox Code Playgroud)
请注意,它包含一个包$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";
Run Code Online (Sandbox Code Playgroud)
该程序的输出是
Hello, Larry!
Hello, Curly!
Hello, Moe!
Hello, Shemp!
4
calls = I do not think it means what you think it means.
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,包变量是全局变量,因此所有常见的问题和建议都不适用.除非明确提供访问权限,否则MyModule包之外的代码不可能访问其词法$calls.
经验法则是你几乎总是想要使用词法.Damian Conway的Perl最佳实践是直接的:" 永远不要让变量成为模块界面的一部分 "(强调原文).
包变量是全局变量;它们在整个程序(甚至其他模块)的任何地方都可见。当您想要或需要这种程度的可见性和/或外部影响时,它们很有用。例如,Text :: Wrap模块使用它们为包装文本的列数提供单个配置点。此外,程序包变量允许您使用一种称为“动态作用域”的方法-但这是一个有点高级且有点深奥的概念。
关于第二个问题,请参阅我和我们的Perl有什么区别?