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); ##</code><code>## 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 ##</code><code>## SV = NULL(0x0) at 0x1d9ec1c
REFCNT = 1
FLAGS = (PADMY) ##</code><code>## SV = IV(0x1d9ec18) at 0x1d9ec1c
REFCNT = 1
FLAGS = (PADMY,IOK,pIOK)
IV = 4 ##</code><code>## SV = PVIV(0x1d91c34) at 0x1d9ec1c
REFCNT = 1
FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
IV = 4
PV = 0x1dbdf84 "4"\0
CUR = 1
LEN = 4 ##</code><code>## SV = PVIV(0x1d91c34) at 0x1d9ec1c
REFCNT = 1
FLAGS = (PADMY,IOK,pIOK)
IV = 5
PV = 0x1dbdf84 "4"\0
CUR = 1
LEN = 4 ##</code><code>## SV = PVIV(0x1d91c34) at 0x1d9ec1c
REFCNT = 1
FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
IV = 5
PV = 0x1dbdf84 "5"\0
CUR = 1
LEN = 4

http://blob.perl.org/tpc/1998/Perl_Language_and_Modules/Perl%20Illustrated/ 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 perldata 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.

perl 变量详解的更多相关文章

  1. mysql show variables系统变量详解

    mysql系统变量详解 mysqld服务器维护两种变量.全局变量影响服务器的全局操作.会话变量影响具体客户端连接相关操作. 服务器启动时,将所有全局变量初始化为默认值.可以在选项文件或命令行中指定的选 ...

  2. net core体系-web应用程序-4net core2.0大白话带你入门-5asp.net core环境变量详解

    asp.net core环境变量详解   环境变量详解 Windows操作系统的环境变量在哪设置应该都知道了. Linux(centos版本)的环境变量在/etc/profile里面进行设置.用户级的 ...

  3. Maya 常用环境变量详解

    Maya 常用环境变量详解 前言: Maya 的环境变量让用户可以很方便的自定义 Maya 的功能. 在 Maya 的 Help 帮助文档中有专门的一个章节< Environment Varia ...

  4. Shell学习之Bash变量详解(二)

    Shell学习之Bash变量详解 目录 Bash变量 Bash变量注意点 用户自定义变量 环境变量 位置参数变量 预定义变量 Bash变量 用户自定义变量:在Bash中由用户定义的变量. 环境变量:这 ...

  5. asp.net core环境变量详解

    环境变量详解 Windows操作系统的环境变量在哪设置应该都知道了. Linux(centos版本)的环境变量在/etc/profile里面进行设置.用户级的环境变量在其它文件里面,不多说了,有兴趣的 ...

  6. 4、Ubuntu系统环境变量详解

    参考:Linux公社Ubuntu系统环境变量详解 UNIX/Linux系统中的环境变量和库文件的使用方法 由于Linux系统严格的权限管理,造成Ubuntu系统有多个环境变量配置文件,因此我们需要了解 ...

  7. Nginx基础篇(2)- Nginx基本配置文件和变量详解

    Nginx基本配置文件和变量详解 1. 基本配置文件 /etc/nginx/nginx.conf # nginx运行的用户 user nginx; # nginx进程数,建议设置为等于CPU总核心数. ...

  8. 如何查找YUM安装的JAVA_HOME环境变量详解

    如何查找YUM安装的JAVA_HOME环境变量详解  更新时间:2017年10月27日 09:44:56   作者:铁锚   我要评论 这篇文章主要给大家介绍了关于如何查找YUM安装的JAVA_HOM ...

  9. Python变量详解

    Python变量详解 目录 Python变量详解 一.变量的定义 二.变量组成的三部分 2.1 变量名 2.1.1 变量名的命名规范 2.1.2 变量名的命名风格 2.2 赋值符号 2.3 变量值 三 ...

随机推荐

  1. HDU5697 刷题计划 dp+最小乘积生成树

    分析:就是不断递归寻找靠近边界的最优解 学习博客(必须先看这个): 1:http://www.cnblogs.com/autsky-jadek/p/3959446.html 2:http://blog ...

  2. hdu1998 bjfu1272奇数阶幻方构造

    这题就是一个sb题,本来很水,硬是说得很含混.奇数阶幻方构造其实有好多方法,这题既不special judge,也不说清楚,以为这样能把水题变成难题似的,简直想骂出题人. /* * Author : ...

  3. web自动化框架之三获取数据库值与界面值比较~~

    数据库用到的是mysql,框架涉及数据库,主要包含两个方面,一个是每个案例执行完毕后,插入案例相关信息与数据:一个是web界面数据核对的时候,需要从sql中获取某行某列值与界面某个值做比较. 描述:w ...

  4. 使用Redis的理由

    Redis是一个远程内存数据库,它不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型.Redis提供了5种不同类型的数据结构,各式各样的问题都可以很自然地映射到这些数据结构上:Re ...

  5. XAMPP:访问phpmyadmin出错的解决方案

    来源:http://www.ido321.com/1246.html XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建 XAMPP 软件站集成软件包,轻巧,用起来很方便.它提 ...

  6. bzoj 3207 花神的嘲讽计划Ⅰ(哈希法+主席树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3207 [题意] 给定一个文本串,多次询问K长的模式串是否在文本[l,r]区间内出现. ...

  7. flot图表的使用

    Flot是一套用Javascript写的绘制图表用的函式库, 专门用在网页上执行绘制图表功能, 由于Flot利用jQuery所以写出来的, 所以也称它为jQuery Flot ,它的特点是体积小.执行 ...

  8. Android JNI之JAVA与C++对象建立对称关联(JNI优化设计,确保JNI调用的稳定性)

    转载请声明:原文转自:http://www.cnblogs.com/xiezie/p/5930503.html Android JNI之JAVA与C++对象建立对称关联 1.JAVA对象持有C++对象 ...

  9. HDU-4751 Divide Groups 染色问题

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4751 题意:有n个人,每个人都认识一些人,要求把他们分成两个集合,使得两个集合中的人都相符两两认识. ...

  10. ProtoBuffer 简单例子

    最近学了一下protobuf,写了一个简单的例子,如下: person.proto文件 message Person{ required string name = 1; required int32 ...