taoyx.log co"> 符号引用(typeglob,别名)与全局变量的修改 - 11GX
首页 > 符号引用(typeglob,别名)与全局变量的修改

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

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



sub change {

        local(*alias) = @_;

        print "$alias ";

        $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, " ";



        $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(' ', );



¶ms(*n);



sub params {

        local (*arr) = @_;



        print 'The values of the @arr array are ', @arr, " ";



        print "The first value is $arr[0] ";



        print "the last value is ", pop(@arr), " ";



        foreach $value (@arr) {

                $value += 5;

                print "The value is $value. ";

        }

}

print "Back in main ";

print "The new values are @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, "


&readit (*HD);



sub readit {

        local(*myfile) = @_;       #给本地别名 myfile 赋值,即将别名传递给子例程

        while () {       #别名是文件句柄 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, " ";

print "$arr ";         #arr 已经只能引用数组而不能引用普通变量,这里内容为空



sub alias {     #修改数组

        local (*a) = @_;

        $a[0] = 7;

        pop @a;

}



&alias(*arr);

print "@list ";



$num = 5;

*alnum = $num; # scalar 只引用变量而不能引用数组

print "@alnum ";


运行输出:

$ ./chalias.pl

12345



7 2 3 4

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

更多相关:

  • 多线程编程 mind-Mapping保存有一下导图的xmind文件,可直接获取 互斥变量 互斥对象 ptrhead相关接口 条件变量 future异步访问类 async类 promise类 package_task类...

  • 我们在实际开发的过程中,可能需要某些类的成员变量并不是针对每一个对象的,而是针对每一个类而言的,比如在银行中有一个利率数据,我们希望的是,当一个利率改变的时候,所有的对象都能够看到这个改变的数据,并利用它,而不是每一个对象都有一个利率成员变量。这个时候就设计到了静态成员变量。 一. 内存那些事 静态成员变量是存放在静态...

  • volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。下面举例说明。在DSP开发中,经常需要等待某个事件的触...

  •   引子     阅读以下代码,并尝试分析 代码解析 在主线程中,线程Id为1,为线程变量赋值 变量==d6ff开启一个新的task,此时线程Id为4,变量==d6ff,并调用Task1开启一个同步Task3,线程Id为1。变量==d6ff,修改值==f598此时第二步启动的Task1运行,线程Id为4,变量==d6ff,修改值=...

  • 操作系统基础    操作系统是协调、控制、管理计算机硬件资源与软件资源的控制程序 为什么要用操作系统?    1.操作系统可以把复杂的操作简化给用户使用或者应用程序  2.可以让应用程序对计算机硬件竞争变的有序  一套完整的计算机分为:操作系统、应用程序、计算机硬件 编程语言的分类   机械语言:使用二进制让计算机工作   优点:运行...

  •  ★ 相同点:     1. 都是地址的概念;     指针指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名。     ★ 区别:     1. 指针是一个实体,而引用仅是个别名;     2. 引用使用时无需解引用(*),指针需要解引用;     3. 引用只能在定义时被初始化一次,之后不可变;指针可变�...

  • 在C++中,&既有引用又有取地址,其实他们的区别可以用一句话概括:=号左边是引用,=号右边是取址。 比如   int a=3;     int &b=a;//引用;                                                    int *p=&a; //取地址 引用b,它是变量a的引用,即别...

  • #coding:utf-8'''Created on 2017年10月25日@author: li.liu'''import pymysqldb=pymysql.connect('localhost','root','root','test',charset='utf8')m=db.cursor()'''try:#a=raw_inpu...

  • python数据类型:int、string、float、boolean 可变变量:list 不可变变量:string、元组tuple 1.list list就是列表、array、数组 列表根据下标(0123)取值,下标也叫索引、角标、编号 new_stus =['刘德华','刘嘉玲','孙俪','范冰冰'] 最前面一个元素下标是0,最...

  • from pathlib import Path srcPath = Path(‘../src/‘) [x for x in srcPath.iterdir() if srcPath.is_dir()] 列出指定目录及子目录下的所有文件 from pathlib import Path srcPath = Path(‘../tenso...

  • 我在使用OpenResty编写lua代码时,需要使用到lua的正则表达式,其中pattern是这样的, --热水器设置时间 local s = '12:33' local pattern = "(20|21|22|23|[01][0-9]):([0-5][0-9])" local matched = string.match(s, "...

  • 在分析ats的访问日志时,我经常会遇到将一些特殊字段对齐显示的需求,网上调研了一下,发现使用column -t就可以轻松搞定,比如 找到ATS的access.log中的200响应时间过长的日志 cat access.log | grep ' 200 ' | awk -F '"' '{print $3}' > taoyx.log co...