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。
对应变量的GV可以用*var 来表示,字段GvstaSH 表示字段所在的命名空间,默认有一个main 命名空间。所有存储于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。如下所示整体命名空间结构:
示例察看main 空间的内容,*:: 等同于*main::
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的整体有一个了解,相信其他语言也有类似的概念结构来实现命名空间的引入。 总结
以上是内存溢出为你收集整理的Perl 内部结构详解 -- PerlGuts Illustrated (5 GV & Stash)全部内容,希望文章能够帮你解决Perl 内部结构详解 -- PerlGuts Illustrated (5 GV & Stash)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)