看一些模块的代码,很多时候通过*glob的方式来改变变量或者函数,这种方法称为Symbolic reference。
首先看一下*glob的结构,这个在之前的博文已经讲过,不做细述:
SV = PVGV(0x18d1364) at 0x182aaec REFCNT = 2 FLAGS = (IN_PAD) NAME = "test" NAMELEN = 4 GvSTASH = 0x298fc4 "main" GP = 0x18b90ac SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x0 CVGEN = 0x0 LINE = 4 FILE = "test.pl" FLAGS = 0x8 EGV = 0x182aaec "test"
运行下边的代码段,察看一下输出对应的ref slot。
print ref \1; print ref \'testing'; print ref [qw(one, two ,three)]; print ref {}; print ref sub {};
如何给*glob赋值?通过下面的方式,填充Symbol的不同slot,从而使得对应的$test,@test,%test,&test非空。
use Data::Dumper; use Devel::Peek; *test = \1; *test = [qw(one two three)]; *test = {qw(one two three four)}; *test = sub {}; print Dump *test;
SV = PVGV(0x18d134c) at 0x182aaec REFCNT = 6 FLAGS = (MULTI,ASSUMECV,IN_PAD) NAME = "test" NAMELEN = 4 GvSTASH = 0x298fc4 "main" GP = 0x18b9104 SV = 0x182aadc REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x2990d4 HV = 0x299214 CV = 0x18b1e7c CVGEN = 0x0 LINE = 4 FILE = "test.pl" FLAGS = 0xe EGV = 0x182aaec "test"
如何使用?use strict情况下有几种方式:
下面的情况直接调用Symbol或者通过our定义直接访问变量,函数无需our定义,总是一个Symbol,可以直接通过名字访问。
use strict; use Data::Dumper; use Devel::Peek; *test = \1; *test = [qw(one two three)]; *test = {qw(one two three four)}; *test = sub {print "testing\n";}; print $::test; print %::test; &test(); our ($test, %test); print $test; print %test; &test;
如果通过一个变量传名字访问另外一个变量,则需要通过下面的方式no strict 'refs'。
no strict 'refs'; print ${'test'}; print %{'test'}; &{'test'};