这是 perldebtut 命令,可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器
程序:
您的姓名
perldebtut - Perl 调试教程
商品描述
使用 perl 调试器的(非常)轻量级介绍,以及指向
有关调试 perl 程序主题的现有、更深入的信息来源。
外面有很多人似乎什么都不知道
关于使用 perl 调试器,尽管他们每天都使用该语言。 这是给他们的。
使用 严格
首先,你可以做一些事情来让你的生活更简单
在调试 perl 程序时,根本不使用调试器。 到
演示,这是一个简单的脚本,名为“hello”,有一个问题:
#!/usr/bin/perl
$var1 = '你好世界'; #一直想这样做:-)
$var2 = "$varl\n";
打印 $var2;
出口;
虽然这编译并愉快地运行,但它可能不会做预期的事情,即
根本不打印“Hello World\n”; 另一方面,它会完全按照原样做
被告知要这样做,计算机有点倾向于这种方式。 也就是说,它会打印出一个换行符
字符,你会得到看起来像一个空行的东西。 看起来有2个变量
当(因为打字错误)真的有 3 个:
$var1 = '你好世界';
$varl = undef;
$var2 = "\n";
为了解决这种问题,我们可以强制每个变量在使用前声明
通过放置“use strict;”来拉入严格模块; 在脚本的第一行之后。
现在当你运行它时,perl 会抱怨 3 个未声明的变量,我们得到了四个错误
消息,因为一个变量被引用了两次:
全局符号“$var1”需要在 ./t1 第 4 行显式包名称。
全局符号“$var2”需要在 ./t1 第 5 行显式包名称。
全局符号“$varl”需要在 ./t1 第 5 行显式包名称。
全局符号“$var2”需要在 ./t1 第 7 行显式包名称。
由于编译错误,./hello 的执行中止。
好开心! 为了解决这个问题,我们显式声明了所有变量,现在我们的脚本看起来
喜欢这个:
#!/usr/bin/perl
用严格;
我的 $var1 = 'Hello World';
我的 $varl = undef;
我的 $var2 = "$varl\n";
打印 $var2;
出口;
然后我们在尝试再次运行之前进行(总是一个好主意)语法检查:
> perl -c 你好
你好语法确定
现在当我们运行它时,我们仍然得到 "\n",但至少我们知道为什么。 刚刚得到这个
要编译的脚本暴露了 '$varl'(带有字母 'l')变量,并且简单地
将 $varl 更改为 $var1 可以解决问题。
展望 at data 和 -w 和 v
好的,但是当你想真正看到你的数据时,动态变量中有什么,
就在使用之前?
#!/usr/bin/perl
用严格;
我的 $key = '欢迎';
我的 %data = (
'这个' => qw(that),
'汤姆' => qw(和杰瑞),
'欢迎' => q(Hello World),
'zip' => q(欢迎),
);
我的@data = 键 %data;
打印 "$data{$key}\n";
出口;
看起来不错,在通过语法检查(perl -c scriptname)之后,我们运行它,所有
我们又得到了一个空行! 嗯嗯。
这里一种常见的调试方法是随意撒一些打印语句,
在我们打印出我们的数据之前添加一个检查,然后添加另一个:
打印 "All OK\n" if grep($key, keys %data);
打印 "$data{$key}\n";
打印“完成:'$data{$key}'\n”;
然后再试一次:
> perl 数据
一切都好
完毕: ''
在多次盯着同一段代码而没有看到树木的木材之后
有一段时间,我们喝杯咖啡并尝试另一种方法。 也就是说,我们引入
骑兵通过给 perl '-d' 在命令行上切换:
> perl -d 数据
默认模具处理程序已恢复。
从 perl5db.pl 1.07 版加载 DB 例程
提供编辑器支持。
输入 h 或 `hh' 获取帮助,或输入 `man perldebug' 获取更多帮助。
main::(./data:4): 我的 $key = 'welcome';
现在,我们在这里所做的是在我们的脚本上启动内置的 perl 调试器。 它是
停在第一行可执行代码处,等待输入。
在我们继续之前,您会想知道如何退出调试器:只使用
信 'q',而不是 'quit' 或 'exit':
数据库<1> q
>
就是这样,你又回到了主场。
帮助
在您的脚本上再次启动调试器,我们将查看帮助菜单。 有一个
调用帮助的几种方式:一个简单的 'h' 将获得概要帮助列表, '|h'(管道-h)
将通过您的寻呼机(可能是“更多”或“更少”)传递帮助,最后,
'h h' (h-space-h) 将为您提供整个帮助屏幕。 这是摘要页面:
D1h
列出/搜索源代码行:控制脚本执行:
l [ln|sub] 列出源代码 T Stack trace
- 或者 。 列出上一行/当前行 s [expr] 单步 [in expr]
v [line] 围绕第 n 行查看 [expr] 接下来,跳过 subs
f 文件名 查看文件中的源代码重复最后 n 或 s
/模式/?模式? Search forw/backwr 从子程序返回
M 显示模块版本 c [ln|sub] 继续直到位置
调试器控件:L 列表中断/观察/动作
o [...] 设置调试器选项 t [expr] 切换跟踪 [trace expr]
<[<]|{[{]|>[>] [cmd] 做前/后提示 b [ln|event|sub] [cnd] 设置断点
! [N|pat] 重做上一条命令 B ln|* 删除一个/所有断点
H [-num] 显示最后 num 个命令 a [ln] cmd 在行前执行 cmd
= [a val] 定义/列出别名 A ln|* 删除一个/所有动作
h [db_cmd] 获取有关命令 w expr 的帮助 添加监视表达式
hh 完整的帮助页面 W expr|* 删除一个/所有手表 expr
|[|]db_cmd 发送输出到 pager ![!] syscmd 在子进程中运行 cmd
q 或 ^D 退出 R 尝试重新启动
数据检查:expr 执行perl代码,另见:s,n,t expr
x|m expr 在列表上下文中评估 expr,转储结果或列出方法。
p expr 打印表达式(使用脚本的当前包)。
S [[!]pat] 列出子程序名称 [不] 匹配模式
V [Pk [Vars]] 列出包中的变量。 变量可以是 ~pattern 或 !pattern。
X [Vars] 与“V current_package [Vars]”相同。
y [n [Vars]] 列出更高范围内的词法. Vars 与 V 相同。
如需更多帮助,请键入 h cmd_letter,或为所有文档运行 man perldebug。
更多令人困惑的选择,你无法动摇大棒! 它并不像看起来那么糟糕
了解更多关于这一切非常有用,而且也很有趣!
有几个有用的可以立即了解。 你不会认为我们是
目前正在使用任何库,但是'M' 将显示当前哪些模块
已加载,以及它们的版本号,而 'm' 将显示方法,并且 'S' 显示所有
子程序(按模式)如下所示。 'V'和'X' 显示程序中的变量
包范围并且可以受模式约束。
DB<2>S 链
转储变量::字符串化
严格::位
严格::导入
严格::取消导入
使用 'X' 和堂兄弟需要你不要使用类型标识符 ($@%),只使用 'name':
DM<3>X~错误
文件句柄(标准错误)=> 文件编号(2)
记住我们在我们的小程序中有问题,我们应该看看我们在哪里,
以及我们的数据是什么样的。 首先让我们看看我们现在位置的一些代码
(本例中的第一行代码),通过 'v':
DB<4> v
1#!/usr/bin/perl
2:使用严格;
3
4==> 我的 $key = '欢迎';
5:我的 %data = (
6 '这个' => qw(that),
7 '汤姆' => qw(和杰瑞),
8 '欢迎' => q(Hello World),
9 'zip' => q(欢迎),
10);
在第 4 行是一个有用的指针,它告诉你你现在在哪里。 查看更多
代码,再次输入“v”:
DB<4> v
8 '欢迎' => q(Hello World),
9 'zip' => q(欢迎),
10);
11: 我的@data = 键 %data;
12: 打印 "All OK\n" if grep($key, keys %data);
13: 打印 "$data{$key}\n";
14:打印“完成:'$data{$key}'\n”;
15:退出;
如果您想再次列出第 5 行,请输入“l 5”(注意空格):
DB<4> l 5
5:我的 %data = (
在这种情况下,没什么可看的,但当然通常会有几页的东西要看
趟过去,'l' 非常有用。 要将您的视图重置为我们即将执行的行
执行,输入一个单独的句点“.”:
数据库<5>。
main::(./data_a:4): 我的 $key = 'welcome';
显示的行是即将执行的行 下页,它还没有发生。 所以
虽然我们可以用字母 ' 打印一个变量p',此时我们得到的只是一个空的
(未定义)值返回。 我们需要做的是单步执行下一个可执行文件
带有 ' 的语句s':
DB<6>
main::(./data_a:5): 我的 %data = (
main::(./data_a:6): 'this' => qw(that),
main::(./data_a:7): 'tom' => qw(and jerry),
main::(./data_a:8): '欢迎' => q(Hello World),
main::(./data_a:9): 'zip' => q(welcome),
主要::(./data_a:10):);
现在我们可以看看第一个 ($key) 变量:
DB<7> p $key
欢迎进入
第 13 行是动作所在,所以让我们通过字母 ' 继续往下看c', 哪一个
顺便说一下,在给定的行或子例程中插入一个“一次性”断点:
DB<8> c 13
一切都好
main::(./data_a:13): 打印 "$data{$key}\n";
我们已经通过了支票(打印了“一切正常”)并在
我们的任务的肉。 我们可以尝试打印出几个变量来看看是什么
发生:
DB<9> p $data{$key}
里面不多,让我们看看我们的哈希:
DB<10> p % 数据
Hello Worldziptoandwelcomejerrywelcomethisthat
DB<11> p 键 %data
Hello World tomwelcomejerrythis
嗯,这不是很容易阅读,并且使用有用的手册(h h), 这 'x' 命令
看起来很有希望:
DB<12> x %数据
0 '你好世界'
1个“拉链”
2“汤姆”
3 '和'
4 '欢迎'
5 未定义
6'杰瑞'
7 '欢迎'
8'这个'
9'那个'
这没什么帮助,那里有几个欢迎,但没有迹象表明哪些是钥匙,
哪些是值,它只是一个列出的数组转储,在这种情况下,不是特别
有帮助。 这里的诀窍是使用 参考 到数据结构:
DB<13> x \%data
0 HASH(0x8194bc4)
'你好世界' => 'zip'
'杰瑞' => '欢迎'
'这个' => '那个'
'汤姆' => '和'
'欢迎' => undef
引用确实被丢弃了,我们终于可以看到我们在处理什么了。 我们的报价
完全有效但对我们的目的来说是错误的,“and jerry”被视为 2
将单词而不是短语分开,从而将均匀配对的哈希结构从
对准。
''-w' switch 会告诉我们这个,如果我们在开始时使用它,并为我们节省了
很多麻烦:
> perl -w 数据
./data 行 5 处散列分配中的奇数元素。
我们修复了我们的引用:'tom' => q(and jerry),然后再次运行它,这次我们得到了预期的结果
输出:
> perl -w 数据
你好世界
当我们在这里时,仔细看看'x' 命令,它真的很有用,并且会
愉快地转储嵌套引用、完整对象、部分对象 - 差不多
无论你扔什么:
让我们快速创建一个对象并对其进行 x-plode,首先我们将启动调试器:它需要一些
来自 STDIN 的输入形式,所以我们给它一些非承诺的东西,一个零:
> perl -de 0
默认模具处理程序已恢复。
从 perl5db.pl 1.07 版加载 DB 例程
提供编辑器支持。
输入 h 或 `hh' 获取帮助,或输入 `man perldebug' 获取更多帮助。
主::(-e:1): 0
现在在几行上构建一个动态对象(注意反斜杠):
DB<1> $obj = bless({'unique_id'=>'123', 'attr'=> \
续:{'col' => 'black', 'things' => [qw(this that etc)]}}, 'MY_class')
让我们来看看它:
DB<2> x $obj
0 我的班级=HASH(0x828ad98)
'属性' => HASH(0x828ad68)
'col' => '黑色'
“东西”=> ARRAY(0x828abb8)
0'这个'
1'那个'
2 '等'
'unique_id' => 123
数据库<3>
有用吧? 您几乎可以评估其中的任何内容,并尝试使用一些代码或
正则表达式直到奶牛回家:
DB<3> @data = qw(这就是另一个无神论皮革理论镰刀)
DB<4> p 'saw -> '.($cnt += map { print "\t:\t$_\n" } grep(/the/, sort @data))
无神论
皮革
other
大镰刀
这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。
理论
锯 -> 6
如果要查看命令历史记录,请键入“H':
DB<5>H
4: p 'saw -> '.($cnt += map { print "\t:\t$_\n" } grep(/the/, sort @data))
3:@data = qw(这是另一个无神论皮革理论镰刀)
2: x $对象
1: $obj = bless({'unique_id'=>'123', 'attr'=>
{'col' => 'black', 'things' => [qw(this that etc)]}}, 'MY_class')
数据库<5>
如果您想重复之前的任何命令,请使用感叹号:'!':
数据库<5> !4
p 'saw -> '.($cnt += map { print "$_\n" } grep(/the/, sort @data))
无神论
皮革
other
大镰刀
这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。
理论
锯 -> 12
有关参考的更多信息,请参阅 perlref 和 perlreftut
步进 通过 码
这是一个在摄氏度和华氏度之间转换的简单程序,它也有
问题:
#!/usr/bin/perl -w
用严格;
我的 $arg = $ARGV[0] || '-c20';
如果 ($arg =~ /^\-(c|f)((\-|\+)*\d+(\.\d+)*)$/) {
我的 ($deg, $num) = ($1, $2);
我的 ($in, $out) = ($num, $num);
如果($deg eq'c'){
$deg = 'f';
$out = &c2f($num);
} {
$deg = 'c';
$out = &f2c($num);
}
$out = sprintf('%0.2f', $out);
$out =~ s/^((\-|\+)*\d+)\.0+$/$1/;
打印 "$out $deg\n";
} {
打印“用法:$0 -[c|f] num\n”;
}
出口;
子 f2c {
我的 $f = 班次;
我的 $c = 5 * $f - 32 / 9;
返回 $c;
}
子 c2f {
我的 $c = 班次;
我的 $f = 9 * $c / 5 + 32;
返回 $f;
}
出于某种原因,华氏到摄氏的转换无法返回预期的输出。
这是它的作用:
> 温度 -c0.72
33.30˚F
> 温度 -f33.3
162.94Ç
不是很一致! 我们将在代码中手动设置断点并在
调试器看看发生了什么。 断点是一个标志,调试器将运行到该标志
没有中断,当它到达断点时,它将停止执行并提供一个
提示进一步互动。 在正常使用中,这些调试器命令完全
忽略,它们是安全的 - 如果有点乱,留在生产代码中。
我的 ($in, $out) = ($num, $num);
$DB::single=2; # 在第 9 行插入!
如果($deg eq 'c')
...
> perl -d temp -f33.3
默认模具处理程序已恢复。
从 perl5db.pl 1.07 版加载 DB 例程
提供编辑器支持。
输入 h 或 `hh' 获取帮助,或输入 `man perldebug' 获取更多帮助。
main::(temp:4): 我的 $arg = $ARGV[0] || '-c100';
我们将简单地继续使用 'c':
数据库<1> c
main::(temp:10): if ($deg eq 'c') {
后面跟着一个view命令,看看我们在哪里:
DB<1> v
7: 我的 ($deg, $num) = ($1, $2);
8: 我的 ($in, $out) = ($num, $num);
9: $DB::单=2;
10==> if ($deg eq 'c') {
11: $deg = 'f';
12: $out = &c2f($num);
13 } 其他 {
14: $deg = 'c';
15: $out = &f2c($num);
16}
并打印以显示我们当前使用的值:
DB<1> p $deg, $num
f33.3
我们可以在任何以冒号开头的行上放置另一个断点,我们将使用第 17 行作为
这就像我们从子程序中出来一样,我们想稍后在那里暂停:
DB<2> b 17
对此没有反馈,但您可以使用列表查看设置了哪些断点
'L' 命令:
DB<3> L
温度:
17: 打印 "$out $deg\n";
中断如果 (1)
请注意,要删除断点,请使用“B”。
现在我们将继续进入我们的子程序,这次而不是按行号,我们将
使用子程序名称,后跟现在熟悉的“v”:
DB<3> c f2c
main::f2c(temp:30): 我的 $f = shift;
DB<4> v
24:退出;
25
26 子 f2c {
27==> 我的 $f = shift;
28:我的 $c = 5 * $f - 32 / 9;
29:返回$c;
30}
31
32 子 c2f {
33:我的 $c = 班次;
请注意,如果在我们和第 29 行之间有一个子程序调用,并且我们想要 单
步 通过它,我们可以使用 's' 命令,并跳过它,我们将使用 'n' 哪一个
将执行 sub,但不会下降到它进行检查。 不过在这种情况下,我们
只需继续向下到第 29 行:
DB<4> c 29
main::f2c(temp:29): 返回 $c;
并查看返回值:
DB<5> p $c
162.944444444444
这根本不是正确的答案,但总和看起来是正确的。 我想知道有没有什么
与运算符优先级有关吗? 我们将用我们的总和尝试其他几种可能性:
DB<6> p (5 * $f - 32 / 9)
162.944444444444
DB<7> p 5 * $f - (32 / 9)
162.944444444444
DB<8> p (5 * $f) - 32 / 9
162.944444444444
DB<9> p 5 * ($f - 32) / 9
0.722222222222221
:-) 这还差不多! 好的,现在我们可以设置我们的返回变量,我们将返回
带有'r'的子:
DB<10> $c = 5 * ($f - 32) / 9
DB<11> r
从 main::f2c 返回的标量上下文:0.722222222222221
看起来不错,让我们继续脚本的结尾:
数据库<12> c
0.72Ç
调试程序终止。 使用 q 退出或 R 重新启动,
使用 O prevent_exit 避免程序终止后停止,
hq、h R 或 h O 以获取更多信息。
快速修复实际程序中的违规行(插入缺少的括号)
我们已经完成了。
占位符 HPMC胶囊 a, w, t, T
操作、观察变量、堆栈跟踪等:在 TODO 列表中。
a
w
t
T
定期 表情
曾经想知道正则表达式是什么样的吗? 你需要用 perl 编译
这个调试标志:
> perl -Dr -e '/^pe(a)*rl$/i'
编译 REx `^pe(a)*rl$'
尺寸 17 先在 2
最稀有的字符
在0
1: BOL(2)
2:精确(4)
4:CURLYN[1] {0,32767}(14)
6: 没有(8)
8:精确(0)
12年: 当(0)
13年: 没有(14)
14:精确(16)
16年: EOL(17)
17年: END(0)
浮动 `'$ 在 4..2147483647(检查浮动)stclass `EXACTF '
锚定(BOL) minlen 4
省略 $` $& $' 支持。
正在执行...
释放 REx:`^pe(a)*rl$'
你真的想知道吗? :-) 有关获取正则表达式的更多详细信息
工作,看看 perlre,perlretut,并解码神秘的标签(BOL 和
CURLYN 等),参见 perldebguts。
OUTPUT TIPS
从错误日志中获取所有输出,并且通过有用的操作不会错过任何消息
系统缓冲,在脚本的开头插入这样的一行:
$|=1;
要查看动态增长的日志文件的尾部,(从命令行):
尾 -f $error_log
将所有 die 调用包装在处理程序例程中对于查看如何以及从何处调用很有用
他们正在被调用,perlvar 有更多信息:
BEGIN { $SIG{__DIE__} = sub { 需要鲤鱼; 鲤鱼::自白(@_) } }
用于重定向 STDOUT 和 STDERR 文件句柄的各种有用技术是
在 perlpentut 和 perlfaq8 中进行了解释。
CGI
这里只是给那些根本不知道如何实现的 CGI 程序员的一个快速提示
当从命令运行他们的 CGI 脚本时,通过“等待输入”提示 -
行,尝试这样的事情:
> perl -d my_cgi.pl -nodebug
当然CGI和perlfaq9会告诉你更多。
图形用户界面
命令行界面与 emacs的 扩展并且有一个 vi
界面也是。
但是,您不必在命令行上执行所有操作,但有一些 GUI 选项
那里。 关于这些的好处是你可以在一个变量和一个转储上挥动鼠标
它的数据会出现在适当的窗口中,或者出现在弹出的气球中,不再烦人
输入'x $varname' :-)
特别是寻找以下内容:
数据库 内置调试器的基于 perlTK 的包装器
DDD 数据显示调试器
开发工具包 和 PerlBuilder 是 NT 特定的
注意。 (有关这些和其他信息的更多信息将不胜感激)。
概要
我们已经看到如何鼓励良好的编码实践 使用 严格 和 -w. 我们可以运行
perl 调试器 perl的 -d 脚本名 从 perl 调试器中检查您的数据
这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 p 和 x 命令。 您可以遍历代码,设置断点 b 和步骤
通过该代码 s or n, 继续 c 并从 sub 返回 r. 相当
当你深入了解它时,直观的东西。
当然还有很多东西需要了解,这只是触及了表面。 这
了解更多信息的最佳方法是使用 perldoc 来了解有关该语言的更多信息,阅读
在线帮助(perldebug 可能是下一个要去的地方),当然还有实验。
使用 onworks.net 服务在线使用 perldebtut