我是Perl编程的真正初学者(Debian 8上的v 5.20.2),我正在寻找一种实现“调试”的方法,在Perl执行时没有开销,而我不需要调试。
在C中,我们可以使用assert
和-D
gcc选项(通常,您可以通过与您自己的定义constante相同的方式执行自己的断言,例如{{1 }})。
嗯,首先想法只是设置一个全局变量MY_DEBUG
并再次测试它,但是当我不想进入调试模式时,它会产生一堆无用的测试。
有CPAN模块,如assertions或Carp::Assert,但即使我不想调试,似乎也会有if测试。
是否有一种Perl方式可以根据“某些内容”停用代码部分?
奖金问题:我想制作一个具有相同功能的Perl模块,所以如果我在debug
做一个方法来说“启用/禁用调试”,那么,我将是一个快乐的Perl显影剂。
答案 0 :(得分:9)
Perl没有内置功能。由于Perl是一种解释型语言,因此也没有像C中那样的编译事件。 Carp::Assert存在的事实(并且由参与Perl核心的人编写)是一个非常好的断言(双关语),这个特性在Perl中不存在。
一般来说,一些if DEBUG
或if $debug
或类似的东西都没什么大不了的。今天的计算机速度如此之快,以至于这些操作几乎不重要,除非你将它们置于一个被称为数百万次的循环中,或者你拥有极其时间关键的代码。在您的普通程序中,您可以忽略该开销。
事实上,如果使用常量,perl 1 将优化它们。考虑一下这个程序。
use constant DEBUG => 1;
print "stuff" if DEBUG;
如果使用B::Deparse运行,则会产生以下输出。
$ perl -MO=Deparse scratch.pl
use constant ('DEBUG', 1);
print 'stuff';
scratch.pl syntax OK
我们的print
声明。但是如果你将DEBUG
常量变为0
并运行相同的命令,你就会得到别的东西。
$ perl -MO=Deparse scratch.pl
use constant ('DEBUG', 0);
'???';
scratch.pl syntax OK
如您所见,print
已消失。剩下的就是'???';
,这是一个NOOP。
让我们用B::Concise运行相同的东西。首先,DEBUG
转为0
。
$ perl -MO=Concise scratch.pl
3 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 120 scratch.pl:1129) v:{ ->3
- <0> ex-const v*/4,FOLD ->3
scratch.pl syntax OK
然后将DEBUG
设置为1
。
$ perl -MO=Concise scratch.pl
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 120 scratch.pl:1129) v:{ ->3
5 <@> print vK/FOLD ->6
3 <0> pushmark s ->4
4 <$> const(PV "stuff") s ->5
scratch.pl syntax OK
如您所见,还有更多操作。 print "stuff" if DEBUG
实际上已经过优化。这与您在C示例中描述的内容几乎完全相同。
继续尝试使用这两个模块,看看在使用Carp::Assert时它是否表现相同。
如果您不喜欢,请查看Smart::Comments。它引入了在use
时执行的注释语法。这很酷,因为当你不加载模块时,那些可以只是坐着而不做事情。
use Smart::Comments; my $var = suspect_value(); ### $var
还有Devel::Comments,似乎也是如此。
1)带有小p的 perl 是解释程序,而不是语言