`
shake863
  • 浏览: 636379 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

perl local my our 的前世今生

    博客分类:
  • perl
阅读更多

Perl中的变量作用范围 local, my, our与全局变量

很古老很古老以前......嗯,不用老到白垩纪,那时候的Perl是自由射击的。没有什么定义变量的说法,所有的变量都是全局变量,也不需要任何 定义就可以使用。后来就出现了local, 再后来出现了use strict 'vars'和my, 再后来又有了our......所以今天的Perl大陆就有了崇山巨岭,一些变量就被限制在盆地里,老死于桃花源中也。

因为要使用一个跨模块全局变量,研究了一下Perl的变量作用范围,写一点笔记吧。

1. 首先说our, 这个最晚出现但其实质却最早出现的变量修饰符。众所周知,在Perl不使用use strict 'vars'的时候,你可以任意使用变量而不需要实现定义:

$szStateMachineStatus = undef;

这行代码在使用了use strict 'vars'以后是编译不能通过的。如果这个变量是一个全局变量,那么可以定义

our $szStateMachineStatus = undef;

这个效果和在不使用use strict 'vars'时一样。"一样"意味着什么呢?

our $szStateMachineStatus = 'init';
{
$szStateMachineStatus = 'inited';
print $szStateMachineStatus;
}
print $szStateMachineStatus;

打印的结果是两个'inited'。顺便说,用our定义过的变量,可以在任何地方被再次用our定义,仍然和第一个our定义的变量是同一个。

2. my

慢慢地有人觉得Perl的"自由射击式"变量定义法则不行,最突出的就是一些常会打错字(typo)的人。假如你定义了一个变量叫$ szStateMachineStatus,可是在某个地方写成了$szStatMachineStatus,少了一个e。因为不use strict啊,所以没有任何警告,可以这样用。结果就是出了错你就慢慢debug去吧,很浪费时间,不符合Perl的懒惰文化。

然后就有了use strict 'vars'和my。有了use strict 'vars'以后,所有的变量在使用前必须先被定义。my的法则很简单,只在当前作用域起作用。比如说定义了
my $szStateMachineStatus;
那么如果是在文件头定义的,作用范围就到文件尾,在子函数里也能用。如果是在子函数里定义的,那么作用范围就只到函数结束。试看以下代码
foreach my $szName (@arrName){
print $szName;
}
在这个循环里Perl每次都创建一个新的$szName变量。换句话说,"my"是属于"见到my就新建"的变量。

3. local

其实这个定义都可以取消了。它是在my还没出现之前的一个权宜方案。比如说一个变量$i被定义成了全局变量,可是你又想暂时使用一个也叫$i的临时变量。
no strict 'vars';
$i = 9999;
{
local $i = 7777;
print "$i\n";
}
print "$i\n";
结果是7777, 9999。在出了local的作用域以后$i又回到了原来的值。在出现了my以后,没有任何理由需要使用local了,请忘记掉它吧。

4. 最后一个话题,全局变量

当你只有一个pl文件时,很简单,把你的全局变量在文件头部定义成our就行。可能你会看到有些书上说要使用use vars qw( $szVersion $szToolName); 这样的方式来把 $szVersion和$szToolName定义成全局变量。注意了,use vars的用法是在my出现后,our出现之前的一个历史的盲肠。our的语法更自然,更易于理解,为什么不用our呢? --另外,在文件头把变量定义成my, 也是全局可用的,但是冒了风险,假如在某个函数里用my再定义一次,原来的值可就消失了。用our就不存在多次定义会导致丢值的状况。

当你在写一个有一个pl文件,N个pm文件的系统时该如何呢?事实上Perl里的变量和函数名都有一个系统级的名字。比如说你在某pm文件的头上定义了包名和全局变量
package bagua;
our $east = 'wood';
那么在任何地方,任何pm和pl文件里都可以使用$bagua::east来访问这个变量。$bagua::east就被称为系统级名字。这也能回答一个问题,为什么不同的perl包里面定义的同名全局变量间不会冲突,因为它们都被限制在包的名字空间下面了。

如果你是在pl里定义全局变量,而且该文件没有定义package名字怎么办?Perl会生成一个缺省的package,名字叫"main"。所以如果你的pl文件是这样
our $szVersion = '1.0.1";
那么在其它文件里就可以用$main::szVersion来访问,并不需要你定义package main.
最后,说一个邪门招式。你可以试一下定义任意一个含有::的变量
our $gColor::Blue = '0x0000FF';
这个变量就在任何地方可用,哪怕你从来没有定义过gColor这个package。这个是Perl的灵活性的体现,它看到这个就自动生成了gColor这个名字空间。当然,我不鼓励这种无厘头的用法。

分享到:
评论
1 楼 hmh1985 2009-08-12  
总结不错。。。

相关推荐

    perl中的范围声明our-my-local介绍

    主要介绍了perl中的范围声明our-my-local介绍,这3个关键字都是控制变量范围的,需要的朋友可以参考下

    perl-local-lib-path.vim:perl-local-lib-path 是 vim 路径的帮手

    perl-local-lib-path perl-local-lib-path是一个帮助程序,可为您的 perl 项目设置 vim 路径。 它会自动将 vim 路径设置为本地 lib 目录,如通过 carton 和 local::lib 安装到您的项目中的extlib和local/perl5/lib ...

    perl脚本perl脚本perl脚本

    perl脚本perl脚本perl脚本perl脚本

    Perl-5.10.0版本

    Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0版本,Perl-5.10.0...

    windows Strawberry Perl 5.32最新版本

    windows Strawberry Perl 5.32最新版本 ,适合调试 perl windows Strawberry Perl 5.32最新版本 ,适合调试 perl windows Strawberry Perl 5.32最新版本 ,适合调试 perl windows Strawberry Perl 5.32最新版本 ...

    centos7 perl rpm依赖包

    perl-Time-Local-1.2300-2.el7.noarch perl-Socket-2.010-3.el7.x86_64 perl-Carp-1.26-244.el7.noarch 4:perl-Time-HiRes-1.9725-3.el7.x86_64 perl-PathTools-3.40-5.el7.x86_64 perl-Scalar-List-Utils-1.27...

    草莓perl安装包下载

    草莓perl安装包下载,新版本 Strawberry Perl是用于MS Windows的perl环境,其中包含运行和开发perl应用程序所需的一切。 它被设计为尽可能接近UNIX系统上的perl环境。 它包括perl二进制文件,编译器(gcc)+相关...

    perl-Time-Local-1.280-1.el8.noarch(1).rpm

    离线安装包,亲测可用

    perl-Time-Local-1.2300-2.el7.noarch.rpm

    离线安装包,亲测可用

    perl教程,txt格式。

    Perl通常位于/usr/local/bin/perl或/usr/bin/perl中。你可以在Internet用匿名FTP免费得到它,如ftp://prep.ai.mit.edu/pub/gnu/perl-5.004.tar.gz。 安装过程为: (1)解压: $gunzip perl-5.004.tar.gz $tar xvf - &...

    perl-Mail-Sendmail

    在perl中使用本机的sendmail发送邮件的代码如下: #!/usr/bin/perl use strict; my($r_mail) = 'xxxx@163.com'; my($s_mail) = 'root@abc.cn'; my($subject) = '邮件标题'; open(MAIL, '|/usr/lib/sendmail -t'); ...

    Intermediate Perl.pdf

    edition of Learning Perl. In the intervening years, Perl itself has grown substantially from a "cool" scripting language used primarily by Unix system administrators to a robust object-oriented ...

    perl的注册表添加(附件Perl.reg)

    win7+bugzilla+apache+mysql+activePerl环境安装bugzill时: Perl安装 安装: 将ActiveState Perl 安装到C:/Perl64 或C:/Perl 最好是5.16版本,ActivePerl-5.16.3.1604-MSWin32-x64-298023.msi 安装 Modules(下面...

    strawberry-perl-5.32.1.1-64bit.msi

    windows环境的perl安装包,不用去官网下载了,测试好用。 strawberry-perl-5.32.1.1-64bit.msi离线安装包(官方),可避免从官网下载速度慢的问题。 windows环境的perl安装包,不用去官网下载了,测试好用。 ...

    perl-Time-Local-1.280-2.module_el8.4.0+646+45e06e4a.noarch.rpm

    离线安装包,亲测可用

    ActivePerl perl 5.12.2.1203 for windows x64 64bit 天涯浪子

    ActivePerl一个可以让你任意执行 Perl 程序的工具软件,其包含了包括有 Perl for Win32、Perl for ISAPI、PerlScript、Perl Package Manager四套开发工具程序,可以让你编写出适用于 unix, windows, linux系统的 CGI...

    perl5.10.1安装文件

    perl5.10.1安装文件perl5.10.1安装文件perl5.10.1安装文件perl5.10.1安装文件perl5.10.1安装文件perl5.10.1安装文件perl5.10.1安装文件

    minimal_perl_for_unix_and_linux_people.pdf

    and also to present talks to our Seattle Perl Users Group (SPUG, aka Seattle.pm). This worked out wonderfully for Seattleites, who would learn practical Perl incantations 1In this book, Unix is ...

    perl脚本(压缩文件夹下文件)上传服务器

    利用perl写一脚本压缩本地文件夹上传到服务器,具体, #!/usr/bin/perl -w use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); use File::Path; use File::Copy; my $zip = Archive::Zip->new(); use strict; my ( $...

    strawberry-perl-5.30.1.1-64bit.zip

    pt-query-digest是一个perl语言编写的脚本,windows环境默认不支持perl,因此需要安装perl脚本的依赖程序。 1、从官网下载草莓perl(完全开源) http://strawberryperl.com/ 2、从此处下载国内镜像

Global site tag (gtag.js) - Google Analytics