GV
GV "Global Value" 或者“符号表”,存储着变量或者函数的指针GP,由GP中slot 相关的指示来决定是否存在对应这个变量相应的类型。如图所示:
GP可以在多个GV中共享,试运行下例查看结果。
D:\perl -MDevel::Peek -e "*test=*Dump; Dump *Dump; Dump *test" SV = PVGV(0x285cda4) at 0x286c0dc REFCNT = 5 FLAGS = (PADTMP,MULTI,ASSUMECV,IN_PAD,IMPORT( CV )) NAME = "Dump" NAMELEN = 4 GvstaSH = 0x3a8fd4 "main" GP = 0x2864ffc SV = 0x0 REFCNT = 2 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x2883874 CVGEN = 0x0 LINE = 67 FILE = "D:/Perl/lib/Exporter.pm" FLAGS = 0x8e EGV = 0x286c0dc "Dump" SV = PVGV(0x285cf04) at 0x285a85c REFCNT = 3 FLAGS = (MULTI,IN_PAD) NAME = "test" NAMELEN = 4 GvstaSH = 0x3a8fd4 "main" GP = 0x2864ffc SV = 0x0 REFCNT = 2 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x2883874 CVGEN = 0x0 LINE = 67 FILE = "D:/Perl/lib/Exporter.pm" FLAGS = 0xa EGV = 0x286c0dc "Dump"
REFCNT 引用数量,上边例子可以观察到。
EGV (effective gv) 表示创建这个GP的GV地址。
LINE 文件中行数。
FILE_HEK 在哪个文件中创建这个GV。
D:\perl -MDevel::Peek -e "$a = 123; Dump *a" SV = PVGV(0x285ced4) at 0x285a82c REFCNT = 3 FLAGS = (MULTI,IN_PAD) NAME = "a" NAMELEN = 1 GvstaSH = 0x3a8f9c "main" GP = 0x286438c SV = 0x285a83c REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x0 CVGEN = 0x0 LINE = 1 FILE = "-e" FLAGS = 0xa EGV = 0x285a82c "a"
如果是从其它模块中引入的,则是通过Export引入main命名空间,实际指向的还是原始模块中的GV,看以下两个例子,函数Dump CV相同。
D:\Tmp>perl -MDevel::Peek -e "Dump *Devel::Peek::Dump" SV = PVGV(0x285c894) at 0x286c714 REFCNT = 3 FLAGS = (MULTI,IN_PAD) NAME = "Dump" NAMELEN = 4 GvstaSH = 0x285aa0c "Devel::Peek" GP = 0x2874484 SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x2883854 CVGEN = 0x0 LINE = 44 FILE = "D:/Perl/lib/Devel/Peek.pm" FLAGS = 0xa EGV = 0x286c714 "Dump" D:\Tmp>perl -MDevel::Peek -e "Dump *Dump" SV = PVGV(0x285cd8c) at 0x286c0f4 REFCNT = 3 FLAGS = (PADTMP,IMPORT( CV )) NAME = "Dump" NAMELEN = 4 GvstaSH = 0x3a8fc4 "main" GP = 0x2864fe4 SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x2883854 CVGEN = 0x0 LINE = 67 FILE = "D:/Perl/lib/Exporter.pm" FLAGS = 0x8e EGV = 0x286c0f4 "Dump"
Stashes
GVs 同Stashes 共同作用实现了Perl 的命名空间,Stash 实际是HV,所有内容都指向GV。命名空间root 是defstash,指向main Stash。一个多层次模块,每一层都有一个相应的Stash。如下所示整体命名空间结构:
D:\Tmp>perl -MDevel::Peek -e "Dump *::" SV = PVGV(0x2851fdc) at 0x3a8fe4 REFCNT = 2 FLAGS = (READONLY,IN_PAD) NAME = "main::" NAMELEN = 6 GvstaSH = 0x3a8fc4 "main" GP = 0x2852fd4 SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x3a8fc4 CV = 0x0 CVGEN = 0x0 LINE = 0 FILE = "" FLAGS = 0xa EGV = 0x3a8fe4 "main::"
查看main 中HV 包含的内容,节选了部分来演示:
D:\Tmp>perl -MDevel::Peek -e "Dump \%::,1000" SV = RV(0x3a90e0) at 0x3a90d4 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0x3a8fc4 SV = PVHV(0x3ae2dc) at 0x3a8fc4 REFCNT = 3 FLAGS = (OOK,SHAREKEYS) ARRAY = 0x287b234 (0:74,1:44,2:8,3:2) hash quality = 105.9% KEYS = 66 FILL = 54 MAX = 127 RITER = -1 EITER = 0x0 NAME = "main" BACKREFS = 0x3a8ff4 ...... Elt "Devel::" HASH = 0xfa558e0e SV = PVGV(0x285c314) at 0x285a9cc REFCNT = 1 FLAGS = (MULTI) NAME = "Devel::" NAMELEN = 7 GvstaSH = 0x3a8fc4 "main" GP = 0x28654ac SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x285a9dc CV = 0x0 CVGEN = 0x0 LINE = 4 FILE = "D:/Perl/lib/Devel/Peek.pm" FLAGS = 0x2 EGV = 0x285a9cc "Devel::" ...... Elt "Dump" HASH = 0xbbea0f76 SV = PVGV(0x285cd94) at 0x286c0f4 REFCNT = 2 FLAGS = (PADTMP,IMPORT( CV )) NAME = "Dump" NAMELEN = 4 GvstaSH = 0x3a8fc4 "main" GP = 0x2864fe4 SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x0 CV = 0x2883854 CVGEN = 0x0 LINE = 67 FILE = "D:/Perl/lib/Exporter.pm" FLAGS = 0x8e EGV = 0x286c0f4 "Dump" ...... Elt "main::" HASH = 0x40383f65 SV = PVGV(0x2851fdc) at 0x3a8fe4 REFCNT = 2 FLAGS = (READONLY,IN_PAD) NAME = "main::" NAMELEN = 6 GvstaSH = 0x3a8fc4 "main" GP = 0x2852fd4 SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x3a8fc4 CV = 0x0 CVGEN = 0x0 LINE = 0 FILE = "" FLAGS = 0xa EGV = 0x3a8fe4 "main::" Elt "ENV" HASH = 0x62ffe0d6 SV = PVGV(0x285c2b4) at 0x285a55c REFCNT = 1 FLAGS = (MULTI) NAME = "ENV" NAMELEN = 3 GvstaSH = 0x3a8fc4 "main" GP = 0x285e184 SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x285a56c CV = 0x0 CVGEN = 0x0 LINE = 0 FILE = "-e" FLAGS = 0x2 EGV = 0x285a55c "ENV"
查看多层次模块中的内容:
D:\Tmp>perl -MDevel::Peek -e "Dump \%Devel::,ROK) RV = 0x285a9dc SV = PVHV(0x3ae57c) at 0x285a9dc REFCNT = 2 FLAGS = (OOK,SHAREKEYS) ARRAY = 0x2865534 (0:7,1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 NAME = "Devel" BACKREFS = 0x285a9fc SV = PVAV(0x3aa32c) at 0x285a9fc REFCNT = 2 FLAGS = () ARRAY = 0x286561c FILL = 0 MAX = 3 ARYLEN = 0x0 FLAGS = () Elt No. 0 SV = PVGV(0x285c334) at 0x285a9ec REFCNT = 1 FLAGS = (MULTI) NAME = "Peek::" NAMELEN = 6 GvstaSH = 0x285a9dc "Devel" GP = 0x28655dc SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x285aa0c CV = 0x0 CVGEN = 0x0 LINE = 4 FILE = "D:/Perl/lib/Devel/Peek.pm" FLAGS = 0x2 EGV = 0x285a9ec "Peek::" Elt "Peek::" HASH = 0xf40ca9c SV = PVGV(0x285c334) at 0x285a9ec REFCNT = 1 FLAGS = (MULTI) NAME = "Peek::" NAMELEN = 6 GvstaSH = 0x285a9dc "Devel" GP = 0x28655dc SV = 0x0 REFCNT = 1 IO = 0x0 FORM = 0x0 AV = 0x0 HV = 0x285aa0c CV = 0x0 CVGEN = 0x0 LINE = 4 FILE = "D:/Perl/lib/Devel/Peek.pm" FLAGS = 0x2 EGV = 0x285a9ec "Peek::"希望通过这一节都能对Perl的整体有一个了解,相信其他语言也有类似的概念结构来实现命名空间的引入。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。