我和Perl在Perl中有什么区别?

我看到他们都在这个脚本中使用,我正在尝试debugging,文献不清楚。 有人能为我揭穿这个吗?

dynamic范围。 这是一个整洁的概念。 很多人不使用它,也不了解它。

基本上my认为my创build和锚定一个variables的一个块,AKA范围。

 my $foo if (true); # $foo lives and dies within the if statement. 

所以myvariables是你习惯的。 而dynamic范围$ var可以在任何地方声明并在任何地方使用。 所以在local你基本上暂停使用这个全局variables,并使用“本地值”来处理它。 所以local为临时variables创build一个临时范围。

 $var = 4; print $var, "\n"; &hello; print $var, "\n"; # subroutines sub hello { local $var = 10; print $var, "\n"; &gogo; # calling subroutine gogo print $var, "\n"; } sub gogo { $var ++; } 

这应该打印:

 4 10 11 4 

简而言之, my在一个词汇范围内将一个variables标记为私有variables, localvariables在dynamic范围内将其标记为私有variables。

理解my更容易,因为这会创build一个通常意义上的局部variables。 有一个新创build的variables,只能在封闭的词法块中访问,通常用大括号标记。 大括号规则有一些例外,例如:

 foreach my $x (@foo) { print "$x\n"; } 

但这只是Perl做你的意思。 通常你有这样的事情:

 sub Foo { my $x = shift; print "$x\n"; } 

在这种情况下, $x对子程序是私有的,它的作用域被大括号括起来。 需要注意的是,这是与local的对比,是myvariables的范围是相对于你的代码定义的,因为它是写在文件中的。 这是一个编译时间现象。

为了理解local ,您需要根据程序运行时的调用堆栈来思考。 当一个variables是localvariables时,它从local语句执行的local重新定义,直到你将堆栈返回给包含本地块的调用者。

起初可能会造成混淆,所以请考虑以下示例。

 sub foo { print "$x\n"; } sub bar { local $x; $x = 2; foo(); } $x = 1; foo(); # prints '1' bar(); # prints '2' because $x was localed in bar foo(); # prints '1' again because local from foo is no longer in effect 

foo被第一次调用时,它会看到$x的全局值为1.当bar被调用并且local $x运行时,它重新定义堆栈上的全局$x 。 现在,当从bar调用foo时,它将为$x看到2的新值。 到目前为止,这不是很特别,因为没有呼叫local情况,也会发生同样的情况。 神奇的是,当bar返回时,我们退出由local $x创build的dynamic范围,而前面的全局$x又回到了范围内。 所以对于foo的最终调用, $x是1。

你几乎总是想用my ,因为这给你你正在寻找的本地variables。 一旦进入了一个蓝色的月亮, local真的很方便做很酷的事情。

引用学习Perl

但是地方是错误的,至less有误导性的命名。 我们的朋友Chip Salzenberg说,如果他有机会回到时间机器到1986年,给Larry一条build议,他会告诉Larry以“save”这个名字叫本地。 这是因为本地实际上将把给定的全局variables的值保存起来,所以它将在以后自动恢复到全局variables。 (这是正确的:这些所谓的“本地”variables实际上是全局variables!)这种保存和恢复机制与我们已经在foreach循环的控制variables和@_子程序参数数组。

所以, local保存全局variables的当前值,然后将其设置为某种forms的空值。 你会经常看到它用来掠过整个文件,而不是只引导一行:

 my $file_content; { local $/; open IN, "foo.txt"; $file_content = <IN>; } 

调用local $/将inputlogging分隔符(Perl停止读取“行”的值)设置为一个空值,导致太空船操作员读取整个文件,所以它从不碰到inputlogging分隔符。

我不敢相信没有人与马克·杰森·多米诺(Mark Jason Dominus)有关此事的详尽论述联系在一起:

  • 应对范围界定

  • 而事后呢,如果你想知道local什么是好的,
    local七个有用的用途

http://perldoc.perl.org/perlsub.html#Private-Variables-via-my();

与由本地运算符创build的dynamicvariables不同,用my声明的词法variables完全隐藏在外面,包括任何被调用的子例程。 这是真的,如果它是从自己或其他地方调用的相同的子程序 – 每个调用获取自己的副本。

http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local();

局部variables将其列出的variables修改为封闭块的“本地”,eval或FILE – 以及该块内调用的任何子例程。 一个本地只给全局(意义包)variables的临时值。 它不创build一个局部variables。 这被称为dynamic范围界定。 词法范围是用我的,它更像C的自动声明。

我不认为这一点是不清楚的,除了说“本地到封闭区块”,这意味着当区块退出时,原来的价值得以恢复。

那么谷歌真的为你工作在这一个: http : //www.perlmonks.org/?node_id=94007

从链接:

快速总结:'我'创build一个新的variables,'本地'暂时修改variables的值。

即“本地” 临时改变variables的值 ,但只其存在的范围内

一般使用我的,它更快,不会做任何奇怪的事情。

man perlsub

与由本地运算符创build的dynamicvariables不同,用my声明的词法variables完全隐藏在外面,包括任何被调用的子例程。

所以,简单化, my的variables只能在声明的位置显示。 local也使它在调用堆栈中可见。 你通常会想用my而不是local

你的困惑是可以理解的。 词汇范围界定相当容易理解,但dynamic范围界定是一个不同寻常的概念。 由于历史的原因, mylocal的名称有些不准确(或者至less是不直观的),这使得情况变得更糟。

my声明了一个词法variables – 一个从声明点直到封闭块(或文件)结束的可见variables。 它完全独立于其他程序中具有相同名称的其他variables。 这个块是私有的。

另一方面, local则声明临时改变一个全局variables的值。 更改在封闭范围的末尾结束,但variables – 全局 – 在程序中的任何位置都可见。

作为一个经验法则,使用my的声明你自己的variables和local来控制对Perl的内置variables的变化的影响。

有关更详尽的描述,请参阅Mark Jason Dominus的文章“ 应对范围” 。

本地化是一个较老的本地化方法,从Perl只有dynamic范围的时代开始。 词法范围对程序员来说更自然,在很多情况下更安全。 我的variables属于它们声明的范围(块,包或文件)。

本地variables实际上属于全局名称空间。 如果你用local引用一个variables$ x,你实际上是指$ main :: x,它是一个全局variables。 与它的名字暗示的相反,所有本地操作都将一个新值添加到$ main :: x的一堆值中,直到此块的结尾,此时旧值将被恢复。 这本身就是一个非常有用的特性,但是有一些原因让局部variables不是一个好方法(想想当你有线程的时候会发生什么!当你调用一个真正想要使用全局的例程时会发生什么?你已经本地化!)。 但是,在Perl 5之前的那些糟糕的日子里,只有variables看起来像局部variables的唯一方法。我们仍然坚持着。

“我的”variables仅在当前代码块中可见。 “本地”variables在以前可见的地方也是可见的。 例如,如果你说“my $ x” 并调用一个子函数,它不能看到这个variables$ x。 但如果你说“本地$ /” (为了清空logging分隔符的值),那么你就改变了从你所调用的函数中读取文件的方式。

在实践中,你几乎总是想要“我的”,而不是“本地的”。

看看下面的代码和它的输出来了解不同之处。

 our $name = "Abhishek"; sub sub1 { print "\nName = $name\n"; local $name = "Abhijeet"; &sub2; &sub3; } sub sub2 { print "\nName = $name\n"; } sub sub3 { my $name = "Abhinav"; print "\nName = $name\n"; } &sub1; 

输出是:

 Name = Abhishek Name = Abhijeet Name = Abhinav 

dinomite的使用本地重新定义logging分隔符的例子是我遇到过很多perl编程的唯一时间。 我住在一个小型的perl环境(安全编程)中,但是在我的经验中它确实是一个很less使用的范围。

 &s; sub s() { local $s="5"; &b; print $s; } sub b() { $s++; } 

上面的脚本打印6。

但如果我们改变本地,我会打印5。

这是不同的。 简单。

我觉得最简单的方法就是这样。 MY创build一个新的variables。 LOCAL临时更改现有variables的值。