什么时候应该使用包变量和词法变量(有什么区别)?

发布于 2024-07-25 05:04:08 字数 413 浏览 9 评论 0原文

我正在 Perl Monks 上查看一些较旧的 Perl 代码,以了解如何使用 Win32 进行编程:: OLE 和 MS Word。 整个代码中散布着名称类似于 $MS::Word 等的变量,但其声明中不包含“my”。 在 Google 上阅读了一些内容后,我了解到这些变量被称为“包变量”,而不是使用 my 声明的“词法变量”。

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

I'm looking at some older Perl code on Perl Monks to figure out programming with Win32::OLE and MS Word. Scattered throughout the code are variables with names like $MS::Word and the like, without a 'my' included in their declaration. After reading a bit on Google, I understand that these are called 'package variables' versus 'lexical variables' declared using my.

My first question is 'What are package variables good for?'. I (think) I understand what lexical variables are, but I don't understand the purpose of package variables or how their use differs from lexicals, so my second question would be, 'What is the difference between lexical and package variables?'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ヅ她的身影、若隐若现 2024-08-01 05:04:08

您应该阅读 MJD 的应对范围界定

perldoc perlmod 也将是有用的阅读。

该代码非常丑陋。 它践踏各种名称空间而无需担心,只是因为作者似乎认为 $author::email 很酷。

更好的方法是使用散列:

my %author = (
   email => '[email protected]',
   ...
);

不需要遍历整个符号表。

我确实有一些 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:我相信我的摘录构成合理使用。

You should read Coping with Scoping by MJD.

perldoc perlmod would also be useful reading.

The code is out of this world ugly. It tramples on all sorts of namespaces without a concern in the world just because the author seems to think $author::email is cool.

A better way would have been to use a hash:

my %author = (
   email => '[email protected]',
   ...
);

Trampling all over the symbol table is not necessary.

I do have a few Win32::OLE examples: http://www.unur.com/comp/ which are no works of art but I believe are improvements on this style. See also Why are the number of pages in a Word document different in Perl and Word VBA?

I am going to rant a little:

@pgm::runtime_args = @ARGV ;

So, we give up on the standard @ARGV array to trample on the pgm namespace. Not only that, every Perl programmer knows what @ARGV is. In any case, @pgm::runtime_args is not used again in the script.

$pgm::maxargs = $#pgm::runtime_args + 1 ;

Of course @pgm::runtime_args in scalar context would give us the number of elements in that array. I have no idea why $pgm::maxargs might be needed, but if it were, then this line should have been:

$pgm::maxargs = @pgm::runtime_args;

I am not going quote more of this stuff. I guess this is what happens when Cobol programmers try to write Perl.

$program::copyright = "Copyright (c) 02002 - Kenneth Tomiak : All rights reserved.";

I am glad he allocated five digits for the year. Ya never know!

PS: I believe my excerpts constitute fair use.

梦明 2024-08-01 05:04:08

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

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

如您所见,包变量是全局变量,因此所有常见的陷阱和建议都适用。 除非显式提供访问权限,否则 MyModule 包外部的代码不可能访问其词法 $calls

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

A package variable lives in a symbol table, so given its name, it's possible to read or modify it from any other package or scope. A lexical variable's scope is determined by the program text. The section "Private Variables via my()" in the perlsub manpage gives more detail about defining lexicals.

Say we have the following 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;

Notice that it contains a package $calls and a lexical $calls. Anyone can get to the former, but the module controls access to the latter:

#! /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";

The program's output is

Hello, Larry!
Hello, Curly!
Hello, Moe!
Hello, Shemp!
4
calls = I do not think it means what you think it means.

As you can see, package variables are globals, so all the usual gotchas and advice against apply. Unless explicitly provided access, it's impossible for code outside the MyModule package to access its lexical $calls.

The rule of thumb is you very nearly always want to use lexicals. Perl Best Practices by Damian Conway is direct: "Never make variables part of a module's interface" (emphasis in original).

童话 2024-08-01 05:04:08

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

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

Package variables are global variables; they're visible everywhere in the entire program (even other modules). They're useful when you want or need that level of visibility and/or external influence. For example the Text::Wrap module uses them to allow a single configuration point for the number of columns at which to wrap text. Futhermore, package variables allow you to use something called "dynamic scoping" -- but that's a somewhat advanced and slightly esoteric concept.

For your second question, see What is the difference between my and our in Perl?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文