博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
perl 变量详解
阅读量:6840 次
发布时间:2019-06-26

本文共 6251 字,大约阅读时间需要 20 分钟。

http://www.perlmonks.org/?node_id=933450 use strict;use Devel::Peek;my $a;Dump($a);$a=4;Dump($a);$a eq "13";Dump($a);$a++;Dump($a);print $a;Dump($a);####C:\Users\ian>perl test.plSV = NULL(0x0) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY)SV = IV(0x1d9ec18) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,pIOK)  IV = 4SV = PVIV(0x1d91c34) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)  IV = 4  PV = 0x1dbdf84 "4"\0  CUR = 1  LEN = 4SV = PVIV(0x1d91c34) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,pIOK)  IV = 5  PV = 0x1dbdf84 "4"\0  CUR = 1  LEN = 4SV = PVIV(0x1d91c34) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)  IV = 5  PV = 0x1dbdf84 "5"\0  CUR = 1  LEN = 45####SV = NULL(0x0) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY)####SV = IV(0x1d9ec18) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,pIOK)  IV = 4####SV = PVIV(0x1d91c34) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)  IV = 4  PV = 0x1dbdf84 "4"\0  CUR = 1  LEN = 4####SV = PVIV(0x1d91c34) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,pIOK)  IV = 5  PV = 0x1dbdf84 "4"\0  CUR = 1  LEN = 4####SV = PVIV(0x1d91c34) at 0x1d9ec1c  REFCNT = 1  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)  IV = 5  PV = 0x1dbdf84 "5"\0  CUR = 1  LEN = 4

 

 presents some of the details of how perl stores and keeps track of variables and their values. It is a bit more complex than the simple model presended in  and the commonly used terms "variable" and "value". There are several data structures used and linked to each other in the case of most variables. Depending on the history of the variable, there will be various bits of memory allocated and with more or less current values.

You can follow the evolution of $a at each step in your program by adding a few more Dump calls:

use strict; use Devel::Peek; my $a; Dump($a); $a=4; Dump($a); $a eq "13"; Dump($a); $a++; Dump($a); print $a; Dump($a);

Which produces:

C:\Users\ian>perl test.pl SV = NULL(0x0) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY) SV = IV(0x1d9ec18) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 4 SV = PVIV(0x1d91c34) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 4 PV = 0x1dbdf84 "4"\0 CUR = 1 LEN = 4 SV = PVIV(0x1d91c34) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 5 PV = 0x1dbdf84 "4"\0 CUR = 1 LEN = 4 SV = PVIV(0x1d91c34) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 5 PV = 0x1dbdf84 "5"\0 CUR = 1 LEN = 4 5

The first Dump produces:

SV = NULL(0x0) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY)

At this point, the variable is declared but no value has been assigned. There is a root data structure allocated: SV, but no memory allocated to store a value: the value is undef and a NULL pointer value in the SV structure is sufficient to record this.

After assigning an integer value to the variable, Dump produces:

SV = IV(0x1d9ec18) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 4

Here an IV structure has been allocated and the assigned value, 4, has been stored in it. The pointer in the SV structure now points to the IV structure: it is not a NULL pointer any more. Flags are set to indicate that the variable now contains a valid integer value (IOK and pIOK).

Next you do a string comparison, for which perl needs to convert the variable value to a string. After this Dump shows:

SV = PVIV(0x1d91c34) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 4 PV = 0x1dbdf84 "4"\0 CUR = 1 LEN = 4

The string value could be created, used then discarded, but instead perl updates the stored value, keeping the string value in case it might be used again. The integer value is still correct, so the variable now has two values: an integer value and a string value. Two data structures are used: the original SV and a PVIV structure which contains the integer value and a pointer to the string value. And the flags are updated to indicate that there are valid integer and string values.

Your next operation is to increment $a. This is an operation on its integer value. In this case, perl is frugal and does only enough work to record the result. The integer value is changed but the string value is not changed. Rather, the flags indicating a valid string value are turned off. After this, Dump produces:

SV = PVIV(0x1d91c34) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 5 PV = 0x1dbdf84 "4"\0 CUR = 1 LEN = 4

Note that perl does not bother to change the PVIV structure back to an IV structure. The latter is smaller but the saving of memory would be tiny - not enough to justify the work. So, the PVIV structure remains, and it still points to the memory allocated to hold the string value, which still has the old, but no longer correct string value of the variable. It's OK that the string value is incorrect because the POK and pPOK flags are off, so the value will not be used. This wastes some memory, but saves some CPU.

Then you print the value of $a. Again, a string value is needed. While the PVIV structure has a pointer to a string value, the POK and pPOK flags in the SV are off, so this value isn't used. Instead, perl again converts the current integer value to a string and prints that correct value. And, again, perl saves this value in case it might be used again. So, after printing Dump produces:

SV = PVIV(0x1d91c34) at 0x1d9ec1c REFCNT = 1 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 5 PV = 0x1dbdf84 "5"\0 CUR = 1 LEN = 4

Again there are both integer and string values, and they are current and consistent. The IOK, POK, pIOK and pPOK flags are all set so that in subsequent operations these value might be used.

Note also that the new string value is in the same bit of memory that the original string value was in. No additional memory was needed, so no new memory was allocated. The original memory was re-used. A lot of work has gone into minimizing expensive operations for the sake of performance.

You might try extending your program, assigning a long string value to $a and then dumping it again. If you did, you would see that the same SV and PVIV structures were in use but the IOK and pIOK flags were off and the integer value in the PVIV remained unchanged and the long string was contained in newly allocated memory, as it wouldn't fit in the block originally allocated to hold the previous single character value.

 

转载地址:http://tnzul.baihongyu.com/

你可能感兴趣的文章
iptraf
查看>>
Tomcat JDBC pool源码部析
查看>>
a 伪类在IE6下优先级大于class
查看>>
iOS 导出 ipa 包时 四个选项的意义
查看>>
我的友情链接
查看>>
android 简单解决询问权限问题和apk打包过大问题
查看>>
Android Accessibility学习笔记
查看>>
QEMU用户模式学习笔记
查看>>
两种方法解决mysql主从不同步
查看>>
Lvs+Keepalived+MySQL Cluster架设高可用负载均衡Mysql集群
查看>>
Spring高级应用之注入嵌套Bean
查看>>
mini6410 uboot1.1.6 MMC fat command support
查看>>
系统日志的实践应用
查看>>
基于SmartGwt的分页组件
查看>>
【oraInventory】由OUI-10035和OUI-10033错误引发的关于oraInventory目录位置的思考
查看>>
epoll和select的区别
查看>>
地产浅吟
查看>>
Eclipse实现文件在资源管理器打开并选中
查看>>
我的友情链接
查看>>
网站访问用时统计
查看>>