`
shake863
  • 浏览: 664541 次
  • 性别: 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"。理解这些关键字的作用范围声明对于编写高质量的Perl代码至关重要。接下来,我们将详细探讨这些关键字,并通过代码示例...

    Perl作用域说明

    在Perl中,变量可以通过`my`、`local`或`our`等关键字进行声明。其中,`my`用于声明词法变量,`local`用于改变全局变量的行为,而`our`则声明包变量,使其在模块中可用。 **示例**: ```perl # 使用my声明词法变量...

    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-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...

    Perl语言编程:Programming Perl

    ### Perl语言编程:《Programming Perl》 #### 书籍概述 《Programming Perl》是一本由Larry Wall、Tom Christiansen和Jon Orwant共同撰写的经典Perl编程指南。这本书详细介绍了Perl语言的基础知识、高级特性以及...

    perl_Perl_

    标题中的"perl_Perl_"可能是指一系列关于Perl编程的示例或教程,而描述则提到“读取源文件,将字母大小写转换,最后输出一个新文件”,这是Perl处理文本时常见的任务。 在Perl中,读取文件通常使用内置的文件句柄和...

    Perl 常用函数 初学PERL

    根据提供的文件信息,我们可以归纳出以下几个重要的Perl编程语言中的知识点: ### 1. Perl中的文件句柄(Filehandle) 在Perl编程中,文件句柄是一个非常重要的概念,它用于指向一个打开的文件或设备。Perl提供了...

    Centos7 离线perl-CPAN rpm包

    2. **perl-local-lib-1.008010-4.el7.noarch.rpm**: 这个包是perl-local-lib,它提供了一种方便的方式来在一个独立的环境中安装Perl模块,不干扰系统级别的Perl安装。这对于测试新模块或使用特定版本的模块而不想...

    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 TK 编程指南 (perl_tk_tutorial)

    ### Perl TK 编程指南知识点概述 #### 一、引言 Perl/Tk(也称为pTk)是一种结合了易于配置的Tk8组件工具包与Perl5强大的词法解析、动态内存管理及面向对象能力的模块集合。简而言之,它是一种用于创建带有图形用户...

    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最新版本 ...

    草莓perl安装包下载

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

    strawberry-perl-5.32.1.1-64bit perl 解释器

    Perl是一种高级的、通用的、解释型、动态的编程语言,以其强大的文本处理能力和在系统管理领域的广泛应用而著名。"strawberry-perl-5.32.1.1-64bit" 是一个专为Windows平台设计的Perl解释器,它包含了Perl 5.32.1.1...

    C.Inline.Perl

    my_perl = perl_alloc(); perl_construct(my_perl); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; char* args[] = {"-e", "open my $fh, ', 'test.txt'; print scalar <$fh>;", NULL}; call_argv("main", AV_...

    PERL perl_add_ons 3

    Perl是一种强大的脚本编程语言,尤其在处理文本和系统管理任务方面表现卓越。"perl_add_ons"在Perl世界中通常指的是额外的模块或库,它们扩展了Perl的基础功能,为开发者提供了更多的工具和功能。在本文中,我们将...

    Perl语言学习.pdf

    Perl语言学习 Perl语言是由Larry Wall在20世纪80年代开发的一种开源的高级语言,它结合了低级语言和高级语言的特性,具有速度快、灵活性强和可读性好的特点。Perl语言的产生是为了解决awk语言无法生成报表的问题,...

    PERL LIB的用法

    perl -I /path/to/my/library script.pl ``` 3. **设置`LIB`环境变量**:在启动Perl之前,设置`LIB`环境变量,值为一个或多个路径,用冒号分隔。例如,在Unix/Linux系统中: ``` export LIB=/path/to/my/...

    Perl 6 技术参考手册_PERL技术参考_Perl_

    Perl 6 还引入了词法作用域的 `my` 关键字,以及 `state` 变量,它们在每次调用块时保持状态。 二、文件操作 Perl 6 提供了强大的文件和目录操作接口。你可以使用 `open` 函数打开文件,`slurp` 用于一次性读取整个...

    Perl大骆驼书

    ### Perl大骆驼书知识点解析 #### 一、概述 《Perl大骆驼书》作为Perl编程语言的经典教程之一,以其全面深入的内容受到广大程序员的喜爱。本书覆盖了Perl语言的核心特性与高级用法,旨在帮助读者掌握这门功能强大且...

Global site tag (gtag.js) - Google Analytics