Perl中变量声明的正确方法

Perl中变量声明的正确方法,perl,variables,scope,Perl,Variables,Scope,我有一组3或4个单独的Perl脚本,它们过去是简单管道的一部分,但现在我尝试将它们组合在一个脚本中,以便于使用(目前没有子例程函数)。问题是,在不同的脚本中定义了几个同名的变量。我发现的解决方法是给这些变量赋予不同的名称,但它可能会开始变得混乱,而且这可能不是正确的方法。 我知道全局变量和局部变量的概念,但我不太明白它们到底是如何工作的 处理这类变量有什么经验法则吗?您是否知道有什么好的文档可以帮助您了解可变范围,或者对此有什么建议 谢谢 已编辑:我已经使用“使用警告;使用严格”;并使用“我的”

我有一组3或4个单独的Perl脚本,它们过去是简单管道的一部分,但现在我尝试将它们组合在一个脚本中,以便于使用(目前没有子例程函数)。问题是,在不同的脚本中定义了几个同名的变量。我发现的解决方法是给这些变量赋予不同的名称,但它可能会开始变得混乱,而且这可能不是正确的方法。 我知道全局变量和局部变量的概念,但我不太明白它们到底是如何工作的

处理这类变量有什么经验法则吗?您是否知道有什么好的文档可以帮助您了解可变范围,或者对此有什么建议

谢谢


已编辑:我已经使用“使用警告;使用严格”;并使用“我的”声明变量。实际上,问题可能更多地与作用域块的定义以及如何使它们彼此独立有关…

经验法则是将代码放入子例程中,每个子例程都集中于更大过程中简单、定义良好的部分。从这一决策流中,我们可以得到许多有益的结果,包括您所问的可变范围问题的自然解决方案

sub foo {
    my $x = 99;
    ...
}

sub bar {
    my $x = 1234;  # Won't interfere with foo's $x.
    ...
}
如果出于某种原因,您确实不想这样做,您可以将代码的每个部分包装在作用域块中,并确保使用
my
声明所有变量(您应该经常使用后者):


由于使用了global变量(实际上可能存在于包
main
中),您可能会遇到麻烦。您应该尽量避免使用全局变量

为此,您应该熟悉变量范围的含义。虽然有点过时,但它很好地介绍了这个主题。另请参见和其他人对问题的回答。(简短回答:尽量避免使用。)

变量范围和限制全局变量使用的原则实际上适用于几乎所有的编程语言。您应该养成声明变量的习惯,尽可能接近实际使用变量的位置

最后,为了让自己免于很多头痛,养成以下习惯:

  • 包括
    使用严格
    使用警告,以及
  • 在每个
    sub
    中使用
    my
    声明变量(将这些变量的范围限制在
    sub
(有关此建议的更多信息,请参阅。)


我将这种做法称为“在系好安全带的情况下进行Perl编程。”:-)

您需要给出一个示例,说明您所面临的问题。但重要的是你要了解自己在做什么,而不是依赖经验法则。关于变量作用域,您“不太了解”的是什么?您应该始终
使用strict
,并通过使用
my
声明词法变量来始终使用它们。你可以忘记任何其他类型的变量,除非你在做一些深奥的事情。听起来好像还有一些重构需要完成:你不应该只是把所有的程序连接在一起,而不单独理解它们。我认为这是一个非常糟糕的经验法则。用几个脚本制作一个子程序并将它们放在一个文件中不太可能有好的结果。我看到太多Perl程序看起来像
submain{…};main()
这个建议更糟糕。Perl子例程主要用于,而任意分割代码很少是一个好主意。@Borodin您对我的建议有一种奇怪的解释:“将您的代码放入子例程中,每个子例程都专注于更大过程中简单、定义良好的部分”——换句话说,基本问题分解和模块化设计。不知道为什么你会将其等同于“任意分割代码”,这(当然)是个坏主意。@Borodin:如果代码以单独的脚本开始,这不是任意的分离。@FMc:如果你说每个组成程序都应该在编译中形成一个子例程,然后我认为这不太可能产生一段构造良好的代码。如果你提出“使用子例程”的一般性建议,那么我认为你没有说什么非常有用的话。@PedroA是的,
for
循环确实会创建独立的作用域块,就像子例程一样——但只适用于用
my
声明的词汇范围变量(这是关键要求)。如果使用包范围变量(一个完全独立的主题),则词法范围边界不适用。关于你的问题。。。好的,这是Perl语言本身的一个实现问题(或者对于任何需要实现词法范围行为的编程语言来说)。非常感谢。我还发现这篇文章对这个问题的范围很有用:
{
    my $x = 99;
    ...
}

{
    my $x = 1234;  # Won't interfere with the other $x.
    ...
}