符号引用(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>);

&params(*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

转载于:https://www.cnblogs.com/cosiray/archive/2012/03/21/2409676.html

符号引用(typeglob,别名)与全局变量的修改相关推荐

  1. C之(6)强弱符号引用

    C之(6)强/弱符号/引用 Author: Once Day Date:2023年1月11日 漫漫长路,有人对你微笑过嘛- 参考引用文档: C语言强.弱符号,强.弱引用 - 牧野星辰 - 博客园 (c ...

  2. java符号引用 直接引用_java虚拟机的符号引用和直接引用

    在java中,一个java类将会编译成一个class文件.在编译时,java类并不知道引用类的实际内存地址,因此只能使用符号引用来代替.比如org.simple.People类引用org.simple ...

  3. 栈帧与操作数栈剖析及符号引用与直接引用的转换

    我们知道在Java中异常处理有两种方式,一种是try...catch...一下,这个在上一次[https://www.cnblogs.com/webor2006/p/9706466.html]中已经进 ...

  4. 类的加载流程、反射、直接引用和符号引用

    类加载流程 一个类被加载到虚拟机内存中需要经历几个过程:加载.连接.初始化.其中连接分为三个步骤:验证.准备.解析,下面一个一个说,这个几个阶段虚拟机都干了什么. 总览图 类加载过程总览图如下图: 加 ...

  5. java字面量和符号引用_java中字面量,常量和变量之间的区别(附:Integer缓存机制)...

    一.引子 在各种教科书和博客中这三者经常被引用,今天复习到内存区域,想起常量池中就是存着字面量和符号引用,其实这三者并不是只在java中才有,各个语言中都有类似的定义,所以做一下总结,以示区分. 二. ...

  6. 符号引用重定位 重定位PC相对引用 简单讲解

    目录 链接符号引用重定位 简介 例子 重定位条目 简介 offset type symbol addend 重定位PC相对引用 重定位PC绝对引用 链接符号引用重定位 简介 我们知道一个.c文件可以被 ...

  7. 将mysql的变量置为0_MySQL 8.0 全局变量的修改持久化 set persist

    全局变量的修改持久化 在8之前的版本中,对于全局变量的修改,其只会影响其内存值,而不会持久化到配置文件中.数据库重启,又会恢复成修改前的值.从8开始,可通过SET PERSIST命令将全局变量的修改持 ...

  8. java字面量和符号引用_java -- JVM的符号引用和直接引用

    在JVM中类加载过程中,在解析阶段,Java虚拟机会把类的二级制数据中的符号引用替换为直接引用. 1.符号引用(Symbolic References): 符号引用以一组符号来描述所引用的目标,符号可 ...

  9. java符号引用 直接引用_JVM的符号引用和直接引用

    [导读]在JVM中类加载过程中,在解析阶段,Java虚拟机会把类的二级制数据中的符号引用替换为直接引用. 在JVM中类加载过程中,在解析阶段,Java虚拟机会把类的二级制数据中的符号引用替换为直接引用 ...

最新文章

  1. 运行第一个Docker容器-Docker for Web Developers(1)
  2. php访问父类变量,php – 如何使用parent :: method访问父类中的变量
  3. 达芬奇SP型机器人二度获准FDA,可用于特定耳鼻喉手术...
  4. java免安装版配置,Tomcat(免安装版)的安装与配置 配置成windows服务
  5. unity 的资源加载问题:一旦永久释放了,就再也不能加载了
  6. Most socially-distanced subsequence CodeForces - 1364B(贪心)
  7. ogm session_带有Hibernate OGM的NoSQL –第三部分:在WildFly上构建REST应用程序
  8. 67-Flutter中高德地图插件的使用
  9. nuxt引用static或者assets目录下资源注意事项
  10. poj3190 区间贪心 挑战程序设计竞赛
  11. 云小课|ModelArts Pro 视觉套件:零代码构建视觉AI应用
  12. Android 网络协议
  13. CF probabilities 自制题单
  14. 聚合影视源码搭建教程
  15. 如何进行自学软件测试?
  16. php界面怎么美化,美化你的应用程序的外观界面
  17. mysql删除的表怎么恢复_误删除mysql数据库表该如何恢复操作方法
  18. 微信注册验证成功之后不跳转_微信小号怎么申请(绑定了微信的手机号怎么注册新的微信)...
  19. 99美金和299美金的开发者证书的区别
  20. spring缓存注解@Cacheable和@CacheEvict,设置过期时间和批量模糊删除

热门文章

  1. 【阿里云课程】残差网络原理,结构发展及有效性理解
  2. 【杂谈】言有三一门CSDN视频课赚160万?你想的太、太、太多了
  3. 【图像分类】从数据集和经典网络开始
  4. 【技术综述】深度学习中的数据增强方法都有哪些?
  5. 全球及中国铝拉丝润滑剂行业竞争格局及运营前景研究报告2021-2027年
  6. 关于MetaAPI问题CSDN给的邮件回复
  7. C++函数调用方式(_stdcall, _pascal, _cdecl...)总结 收藏
  8. 世界人民盼丰收-国际农民丰收节贸易会:世界农民节日
  9. 2020(广东)功能性农业大健康大会中国农民丰收节交易会
  10. MySQL 高可用架构 之 MHA (Centos 7.5 MySQL 5.7.18 MHA 0.58)