我和Perl在Perl中有什么区别?
我看到他们都在这个脚本中使用,我正在尝试debugging,文献不清楚。 有人能为我揭穿这个吗?
dynamic范围。 这是一个整洁的概念。 很多人不使用它,也不了解它。
基本上my
认为my
创build和锚定一个variables的一个块,AKA范围。
my $foo if (true); # $foo lives and dies within the if statement.
所以my
variables是你习惯的。 而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, local
variables在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
的对比,是my
variables的范围是相对于你的代码定义的,因为它是写在文件中的。 这是一个编译时间现象。
为了理解local
,您需要根据程序运行时的调用堆栈来思考。 当一个variables是local
variables时,它从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范围界定是一个不同寻常的概念。 由于历史的原因, my
和local
的名称有些不准确(或者至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的值。