Chinaunix首页 | 论坛 | 博客
  • 博客访问: 966627
  • 博文数量: 184
  • 博客积分: 10030
  • 博客等级: 上将
  • 技术积分: 1532
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-27 18:32
文章分类

全部博文(184)

文章存档

2009年(1)

2008年(63)

2007年(39)

2006年(79)

2005年(2)

我的朋友

分类:

2006-12-25 16:59:47

6.13 作用域规则:全局、字典、动态
标识符的“作用域”是指程序中一个特定的部分。只有在这个部分中,才可以对此标识符进行引用。有的标识符可在程序的任何地方引用;另一些则只能在有限的部分总才能引用。
对一个标识符来说,通常可选择3种作用域: 全局作用域、字典作用域、动态作用域。
全局作用域在程序执行的任何阶段都可以使用,而且可在程序任何的地方对其进行修改。
假如不加任何前缀来定义一个变量,那么它会默认为全局变量,有一个全局作用域。
对于“字典作用域”来说,只有在定义它的那个代码块中才能使用它。而对“动态作用域变量”来说,只有从它的创建位置开始,一直到当前块结束前才可以使用它。注意对块内的子程序来说,只要在允许的范围内,那么一样可以访问这些变量。
下面这个程序展示了全局、字典、动态变量的作用域问题。
-------------------------------------------------------------------------
      1 #!/usr/bin/perl
      2 # Fig. 6.16: fig06_16.pl
      3 # Demontrating variable scope.
      4
      5 # before global variables are defined, call subroutine1
      6 print "Without globals:\n";
      7 subroutine1();
      8
      9 # define global variables
     10 our $x = 7;
     11 our $y = 17;
     12
     13 # call subroutine1 to see results with defined global variables
     14 print "\nWith globals:";
     15 print "\nglobal \$x: $x";
     16 print "\nglobal \$y: $y\n";
     17 subroutine1();
     18 print "\nglobal \$x: $x";
     19 print "\nglobal \$y: $y\n";
     20 subroutine2();
     21 # subroutine1 displays its own $x (lexical scope )
     22 # and $y (dynamic scope) variables, then calls subroutine2
     23 sub subroutine1
     24 {
     25    my $x = 10;
     26    local $y = 5;
     27    print "\$x in subroutine1: $x\t(lexical to subroutine1)\n";
     28    print "\$y in subroutine1: $y\t(dynamic to subroutine1)\n";
     29    subroutine2();
     30 }
     31
     32 # subroutine2 displays global $x and subroutine1's $y which
     33 # has dynamic scope
     34 sub subroutine2
     35 {
     36    print "\$x in subroutine2: $x\t(global)\n";
     37    print "\$y in subroutine2: $y\t(dynamic to subroutine1)\n";
     38 }
     39
--------------------------------------------------------------------
程序的输出如下:
Without globals:
$x in subroutine1: 10   (lexical to subroutine1)
$y in subroutine1: 5    (dynamic to subroutine1)
$x in subroutine2:      (global)
$y in subroutine2: 5    (dynamic to subroutine1)
With globals:
global $x: 7
global $y: 17
$x in subroutine1: 10   (lexical to subroutine1)
$y in subroutine1: 5    (dynamic to subroutine1)
$x in subroutine2: 7    (global)
$y in subroutine2: 5    (dynamic to subroutine1)
global $x: 7
global $y: 17
$x in subroutine2: 7    (global)
$y in subroutine2: 17   (dynamic to subroutine1)
 
--------------------------------------------------------------------
 
在这里,our、my、local定义的便是一个变量的作用域。其中,our关键字将一个变量明确定义为全局变量。my关键字定义了一个字典作用域变量。 而local关键字定义了一个动态作用域变量。请记住,在定义中既没有my、也没有local的变量均默认为全局变量。
 
在定义任何全局变量之前,我们先在第7行调用了soubroutine1子程序(定义在第23-30行)。在这个子程序中,我们定义了一个字典变量$x(在第25行使用关键字my),并将其初始化成10,同时定义了一个动态变量$y(在26行使用local定义),并初始化成5。接下来,subroutine1同时显示了两个变量的值。随后,subroutine1会调用subroutine2(定义于第34-38行)。
 
在subroutine2中,我们用第36行显示了$x的值。在这个时候,唯一定义好的$x变量是把字典作用域定在subroutine1之内的那个$x---subroutine2是无法“看到”subroutine1的字典作用域变量的。 因此subroutine2会试着寻找一个全局定义的$x。由于暂时无法找到这样的一个定义,所以不会输出一个值。
在第37行,我们让subroutine2显示了变量$y。该变量在subroutine1中被定义在一个动态作用域内。 subroutine1调用subroutine2时,由于subroutine2可访问subroutine1中所有被定义为动态作用域的变量。因此subroutine2可顺利输出subroutine1中的$y变量的值(等于5)。
subroutine1执行完毕后,程序会跳至第10行继续执行。在这个地方,程序用our关键字定义了全局量$x和$y。其中,$x被设置为7,而$y被设为17。请记住,在定义中既没有my、也没有local的变量均默认为全局变量。
 
良好的编程习惯: 应该用our,my,local明确定义所有变量。
 
提示:our关键字只能用于Perl的5.6及更高版本。
 
 
Perl版主“兰花仙子”的一篇关于变量的作用域的精华文章:
 
阅读(1862) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~