符号引用(typeglob,别名)与全局变量的修改
2012-03-21 13:31
246 查看
符号引用(typeglob,别名)与全局变量的修改
不能以为在子函数里修改了一个和全局变量同名的变量就会修改全局变量:#!/usr/bin/perl $glov = "hello"; change; print $glov; sub change { $glov = "world"; }
虽然在子程序 change 里的 $glov 变量和全局变量 $glov 名字相同,但两个并不是同一个变量,子程序里的变量为局部变量。
在子程序里修改全局变量的一种方法是利用“符号引用”。
符号引用类似与 Linux 里的软连接概念,它又称为别名。创建一个变量的别名的方法是在实际变量的前面加上一个 "*" 符号。星号("*") 适用于任意类型的变量,包括标量,数组,散列,文件句柄,子函数等。
别名是符号表中针对同名标识符的另一个名称,比如 *name 可以表示 $name, @name 以及 %name, &name 等。
当通过别名按引用传递方式将别名传递到函数中时,需要用 local 函数声明一个私有变量用以接收传递进来的别名,该私有变量也就是另外一个别名,然后修改该私有变量也就等效于修改了传递进来的全局变量。如下程序所示:
#!/usr/bin/perl $glov = "hello"; &change(*glov); print $glov, "\n"; sub change { local(*alias) = @_; print "$alias\n"; $alias = "world"; }
运行输出:
$ ./changeglobv.pl
hello
world
上面,不能用 my 来声明这个私有变量,因为 my 函数所创建的变量名称并不保存在符号表中,而是位于临时缓冲区中。由于 typeglob 仅能关联到特定的符号表上,因此 my 不能对它进行私有化,所以要让 typeglob 本地化就必须使用 local 函数。
测试代码2:
#!/usr/bin/perl $colors = "rainbow"; @colors = ("red", "green", "yellow"); &printit(*colors); #传递进 colors 数组的别名 sub printit { local(*whichone) = @_; print *whichone, "\n"; $whichone = "hello world"; $whichone[0] = "BLUE"; #修改数组中的元素 }
运行输出:
$ ./alias.pl
*main::colors #告知 *whichone 是 main 中 colors 的别名
Out of subroutine.
$colors is hello world.
@colors is BLUE green yellow.
测试代码3:
#!/usr/bin/perl @n = split(' ', <STDIN>); ¶ms(*n); sub params { local (*arr) = @_; print 'The values of the @arr array are ', @arr, "\n"; print "The first value is $arr[0]\n"; print "the last value is ", pop(@arr), "\n"; foreach $value (@arr) { $value += 5; print "The value is $value.\n"; } } print "Back in main\n"; print "The new values are @n.\n";
运行输出:
$ ./alias2.pl
1 2 3 4 5 #输入命令行参数
The values of the @arr array are 12345
The first value is 1
the last value is 5
The value is 6.
The value is 7.
The value is 8.
The value is 9.
Back in main
The new values are 6 7 8 9.
测试代码4:
该例子演示通过引用传递文件句柄。如果要直接把文件句柄传递给子函数,唯一的途径就是通过引用(注意,还有个硬引用,这里不涉及)。
#!/usr/bin/perl open (HD, "<hello.txt") || die "Can not open file: $!"; #以只读方式打开文件 hello.txt,并建立相应句柄 HD &readit (*HD); sub readit { local(*myfile) = @_; #给本地别名 myfile 赋值,即将别名传递给子例程 while (<myfile>) { #别名是文件句柄 HD 的另一个名字,while 循环逐行读取文件句柄中的各行内容 print; } }
在上面,别名可以同时匹配多种类型。如果你只想匹配特定的一种,那么此时需要用反斜杠运算符,Perl 的引用机制允许对某类特定变量而不是所有变量类型使用别名,如:
*array = \@array; # *array只引用数组
*scalar = \$scalar; # *saclar 只引用变量
*hash = \%assoc_array; # *hash 只引用散列表
*func = \&subroutine; # *func 只引用子函数
测试代码5:
#!/usr/bin/perl @list = (1, 2, 3, 4, 5); *arr = \@list; #*arr 此时只对 @list 数组引用 print @arr, "\n"; print "$arr\n"; #arr 已经只能引用数组而不能引用普通变量,这里内容为空 sub alias { #修改数组 local (*a) = @_; $a[0] = 7; pop @a; } &alias(*arr); print "@list\n"; $num = 5; *alnum = \$num; # scalar 只引用变量而不能引用数组 print "@alnum\n";
运行输出:
$ ./chalias.pl
12345
7 2 3 4
相关文章推荐
- python 全局变量引用与修改
- python 全局变量引用与修改
- Python多模块全局变量引用和修改
- shell 知识点补充(1)-提示字符的设定/read/declare / typeset/变量设定功能/别名/万用字符与特殊符号
- 函数中“引用”全局变量和“修改”全局变量的差别
- &符号不能被用于左值, 全局变量的地址是唯一的, 不可以修改的一个左值
- Python global全局变量只能在函数中没做global申明,可以引用但修改会报错。
- 内部函数引用外部函数的同名变量或者全局变量,并且对这个变量有修改的报错原因
- JavaScript函数内部修改全局变量的问题【一道面试题】
- node 修改全局环境变量
- VS2008编译环境下全局const变量在其他编译模块中引用注意的问题
- php的引用&(就是在变量或者函数、对象等前面加上&符号)
- 内存问题--全局变量被修改
- 引用 你的变量究竟存储在什么地方 && 全局内存
- php的全局变量在函数里头引用--以及常量
- 不使用引用和全局变量实现函数参数传递
- 零基础学python-16.5 模块间全局变量的修改以及其他访问全局变量的方法
- php方法中引用全局变量要加 global
- Python - 析构修改全局变量异常(__del__ of <__main__)
- 在中断程序里修改全局变量的童鞋注意啦~(C中的volatile作用 转载~)