本文属个人原创,欢迎自由转载。但请标明本文的连接,并保证本文的完整性。
Godbach
2011/05/07
本文的阅读群体定位在 Perl 新手,高手可以直接忽略。:-)
很多编程工具最常用的调试方法都是在一些环节打印出一些信息,然后去判断是否符合预期。比如 C 中 printf,kernel 中 printk。当然,Perl 也不例外,可以用 print 打印消息。
但是,这里我并不是要介绍 print。否则,各位看官除了不屑之外,只有鄙视啦。
这里要介绍两个用于调试的模块: 一个是 Data::Dumper,另一个是 Smart::Comments。且看这两个模块是如何用于调试的。
1. Data::Dumper
一看到有 Dumper 字样,是不是就联想到了 C 中的 coredump,想到了抓包常用的 tcpdump,想到了直接查看文件 16 进制的 hexdump,以及其他一些具有 dump 功能的工具了。
想到了这些,可能就会感觉但凡是带着 dump 字样的东东应改都比较牛叉吧。实际上是不是如此呢,下面咱们就通过实例来说明。
如果大家的环境中还没有安装 Data::Dumper,那就通过 cpan 安装一个包。有网络环境就是好啊,一个命令敲下去,一会儿模块就安装好了,就可以练兵了。
实例如下(dumper.pl):
- #!/usr/bin/perl
- # Godbach, 2011/05/07
-
use warnings;
-
use strict;
-
use Data::Dumper;
-
-
my $var = "Hello, world";
-
my @arr = qw(hello world bye bye);
-
my %foo = (
-
name => 'zhangsan',
-
age => '28',
-
sx => 'male',
-
company => {
-
'intel' => '2',
-
'ibm' => '3',
-
'microsoft' => '2'
-
},
-
);
-
-
# 打印变量
-
print "==> Dump Variable:\n";
-
print Dumper($var);
-
-
# 打印数组
-
print "==> Dump Array:\n";
-
print Dumper(@arr);
-
-
# 打印数组引用
-
print "==> Dump Array ref:\n";
-
print Dumper(\@arr);
-
-
# 打印 hash
-
print "==> Dump Hash:\n";
-
print Dumper(%foo);
-
-
# 打印 hash 引用
-
print "==> Dump Hash ref:\n";
-
print Dumper(\%foo);
-
-
# 打印子 hash
-
print "==> Dump Sub Hash\n";
-
print Dumper($foo{company});
-
-
- exit 0;
该程序使用 Dumper 模块,打印出了 Perl 普通变量、数组、数组引用、hash、hash 引用以及子 hash 的内容。
程序执行结果如下:
[root@Godbach Perl]# ./dumper.pl
==> Dump Variable:
$VAR1 = 'Hello, world';
==> Dump Array:
$VAR1 = 'hello';
$VAR2 = 'world';
$VAR3 = 'bye';
$VAR4 = 'bye';
==> Dump Array ref:
$VAR1 = [
'hello',
'world',
'bye',
'bye'
];
==> Dump Hash:
$VAR1 = 'name';
$VAR2 = 'zhangsan';
$VAR3 = 'company';
$VAR4 = {
'ibm' => '3',
'microsoft' => '2',
'intel' => '2'
};
$VAR5 = 'sx';
$VAR6 = 'male';
$VAR7 = 'age';
$VAR8 = '28';
==> Dump Hash ref:
$VAR1 = {
'name' => 'zhangsan',
'company' => {
'ibm' => '3',
'microsoft' => '2',
'intel' => '2'
},
'sx' => 'male',
'age' => '28'
};
==> Dump Sub Hash
$VAR1 = {
'ibm' => '3',
'microsoft' => '2',
'intel' => '2'
};
从输出结果中,可以看出:
(1)Dumper 最简单的用法,就是将你需要打印的元素传递给 Dumper() 函数即可,同时调用 print 输出结果。
(2)Dumper 打印的结果中所有变量都按照自己的方法进行命名,缺省按照 $VAR1 开始。
(3)在数组和 hash 的打印中,传递数组或 hash 的引用,Dumper 输出的结果会更加容易阅读。可以参见上面输出结果中 Dump Arrary ref 和 Dump Hash ref 部分的结果和直接打印的结果作对比。
总之,Dumper 可以将我们所关心的内容完成的打印出来,让你觉得有问题的地方无所遁逃。
这里只是简单说明 Dumper 的用法,更多的使用细节请通过 perldoc Data::Dumper 查看对应的手册。
2. Smart::Comments
这个模块有个 Smart 字样,表面看起来应该是有比较智能的。且后面看一下有何 Smart 之处。
还是直接上例子吧,详细的使用方法看手册,这里只是展示一下这个模块的简单用法。更多牛叉的细节,还是需要自己实践中挖掘和发现。
笔者是懒人一个,因此还是用上面 dumper.pl 例程中的主题部分,将调用 Dumper 的地方换成 Smart::Comments 所对应的即可。所要打印的内容仍然是包含变量、数组、数组引用、hash、hash 引用和子 hash。
代码如下:
- #!/usr/bin/perl
-
use warnings;
-
use strict;
-
use Smart::Comments;
-
-
my $var = "Hello, world";
-
my @arr = qw(hello world bye bye);
-
my %foo = (
-
name => 'zhangsan',
-
age => '28',
-
sx => 'male',
-
company => {
-
'intel' => '2',
-
'ibm' => '3',
-
'microsoft' => '2'
-
},
-
);
-
-
### $var
-
-
### @arr
-
-
### arr: \@arr
-
-
### %foo
-
-
### foo: \%foo
-
-
### co: $foo{company}
-
- exit 0;
当 use Smart::Comments 时,代码中 '###' 就相当于提示这里要打印信息。要打印的内容,就是 '###' 这个后面的表达式。
运行一把看结果:
[root@Godbach Perl]# ./smart_comments.pl
### $var: 'Hello, world'
### @arr: [
### 'hello',
### 'world',
### 'bye',
### 'bye'
### ]
### \@arr
### %foo: {
### age => '28',
### company => {
### ibm => '3',
### intel => '2',
### microsoft => '2'
### },
### name => 'zhangsan',
### sx => 'male'
### }
### \%foo
### $foo{company}
从这个结果我们可以看出:
(1)不管是变量、数组还是 hash,打印的时候都可以显示对应的名字,这个比 Dumper 的 $VAR1...$VARn 更加易读一些吧。
(2)所有打印出来的信息开头三个字符都是 '#'。这个就算你不小心将此调试信息留在代码中了,而且最终和程序的正常输出混在一起了,简单通过 '###' 也可以区分出来。
(3)这一点应该从代码中看不出来,要看手册。:-)。当把程序调试通过之后,只需通过把代码开头的 use Smart::Comments 注释掉,或者改成 no Smart::Comments 就可以让程序不在输出调试信息。这一点是不是比较爽啊,解除了删除调试信息的苦恼。
(4)是不是发现了,代码中数组的引用、 hash 的引用、子 hash 都没有正确的输出结果,原封不动的把代码输出出来了。这会不会是我们的用法不对,还是我们的用法不对呢。
经过咨询有经验的高手,原来是这种情形需要在前面加个名字,至于什么名字,随意就好了。但是名字后面要跟着':'。对于几个引用和子 hash 修改后的代码如下:
- ### $var
-
-
### @arr
-
-
### arr: \@arr
-
-
### %foo
-
- ### foo: \%foo
然后再查看一下执行结果:
[root@Godbach Perl]# ./smart_comments.pl
### $var: 'Hello, world'
### @arr: [
### 'hello',
### 'world',
### 'bye',
### 'bye'
### ]
### arr: [
### 'hello',
### 'world',
### 'bye',
### 'bye'
### ]
### %foo: {
### age => '28',
### company => {
### ibm => '3',
### intel => '2',
### microsoft => '2'
### },
### name => 'zhangsan',
### sx => 'male'
### }
### foo: {
### age => '28',
### company => {
### ibm => '3',
### intel => '2',
### microsoft => '2'
### },
### name => 'zhangsan',
### *** => 'male'
### }
### co: {
### ibm => '3',
### intel => '2',
### microsoft => '2'
### }
OK。 修改之后就可以正常输出了。至于为什么需要处理,查一下相关的文档吧。
至此,笔者简单介绍了 Perl 中用于调试的两个模块,而且都是简单的介绍。再次强调,要想了解全部的功能,还是要去看文档的。
至于这两个模块哪个好用,见仁见智。用一句流行的说法:适合自己的就是最好的。