在尝试将C语言的assert()
宏实现到Perl中时,会遇到一些基本问题。首先看一下以下代码:
sub assert($$) {
my ($assertion, $failure_msg) = @_;
die $failure_msg unless $assertion;
}
# ...
assert($boolean, $message);
虽然这样可行,但不像C语言的实现,我会写
assert($foo <= $bar)
,但是使用这个实现我需要写assert($foo <= $bar, '$foo <= $bar')
,即以字符串形式重复条件。
现在我想知道如何高效地实现它。简单的方法似乎是将字符串传递给assert()
,并使用eval
来评估字符串,但是当评估eval时无法访问变量。即使它能够工作,每次都要解析和评估条件,这样也会非常低效。
在传递表达式时,我不知道该如何生成字符串,特别是因为它已经被计算了。
另一种使用assert(sub { $condition })
的变体,其中可能更容易从代码引用中制作字符串,但被认为太丑陋了。
使用assert(sub { (eval $_[0], $_[0]) }->("condition"));
结构时,
sub assert($)
{
die "Assertion failed: $_[1]\n" unless $_[0];
}
可以实现,但是调用起来很丑陋。
我正在寻找的 解决方案 是只需检查一次条件,同时能够复制原始(未计算)条件并高效地计算条件。
那么有哪些更优雅的解决方案呢?显然,如果Perl有一个宏或类似语法机制,允许在编译或评估之前转换输入,那么解决方案将更加容易实现。
Filter::Simple
完成吗? - U. Windl