在Perl中是否有可靠地获取当前行号的方法
不显式使用的多行列表分配
__LINE__
?我是
将测试用例存储在列表中,并希望用其行标记每个测试用例
数字。*这样我就可以做(大致上)
ok($_->[1], 'line ' . $_->[0]) for @tests
.
当然,与
放
_线条__
在每个测试用例的开头)。我有
找不到方法,我遇到了一些
报告的行中的混乱行为
caller
.
*可能是xy,但我找不到模块来完成。
更新
我发现了一个黑客并将其发布为
an answer
. 感谢@zdim帮助我以不同的方式思考这个问题!
麦克维尔
很长的一个,因为我试过几种不同的选择。
my_eval
,
L()
和
L2{}
是我到目前为止试过的-
()
是那个
我最初希望能工作。跳到
my @testcases
看看如何
我在用这些。测试时,请复制shebang行。
这是我的
non-MCVE use case
,如果您感兴趣。
#!perl
use strict; use warnings; use 5.010;
# Modified from https://www.effectiveperlprogramming.com/2011/06/set-the-line-number-and-filename-of-string-evals/#comment-155 by http://sites.google.com/site/shawnhcorey/
sub my_eval {
my ( $expr ) = @_;
my ( undef, $file, $line ) = caller;
my $code = "# line $line \"$file\"\n" . $expr;
unless(defined wantarray) {
eval $code; die $@ if $@;
} elsif(wantarray) {
my @retval = eval $code; die $@ if $@; return @retval;
} else {
my $retval = eval $code; die $@ if $@; return $retval;
}
}
sub L { # Prepend caller's line number
my (undef, undef, $line) = caller;
return ["$line", @_];
} #L
sub L2(&) { # Prepend caller's line number
my $fn = shift;
my (undef, undef, $line) = caller;
return ["$line", &$fn];
} #L2
# List of [line number, item index, expected line number, type]
my @testcases = (
([__LINE__,0,32,'LINE']),
([__LINE__,1,33,'LINE']),
(L(2,34,'L()')),
(L(3,35,'L()')),
(do { L(4,36,'do {L}') }),
(do { L(5,37,'do {L}') }),
(eval { L(6,38,'eval {L}') }),
(eval { L(7,39,'eval {L}') }),
(eval "L(8,40,'eval L')"),
(eval "L(9,41,'eval L')"),
(my_eval("L(10,42,'my_eval L')")),
(my_eval("L(11,43,'my_eval L')")),
(L2{12,44,'L2{}'}),
(L2{13,45,'L2{}'}),
);
foreach my $idx (0..$#testcases) {
printf "%2d %-10s line %2d expected %2d %s\n",
$idx, $testcases[$idx]->[3], $testcases[$idx]->[0],
$testcases[$idx]->[2],
($testcases[$idx]->[0] != $testcases[$idx]->[2]) && '*';
}
产量
添加了我的评论。
0 LINE line 32 expected 32
1 LINE line 33 expected 33
使用
_线条__
明确的工作很好,但我正在寻找一个
缩写。
2 L() line 45 expected 34 *
3 L() line 45 expected 35 *
()
使用
呼叫者
获取行号并报告一行
后来
在文件中
(!).
4 do {L} line 36 expected 36
5 do {L} line 45 expected 37 *
当我把
()
呼叫
do{}
,
呼叫者
返回正确的
行号-但只能一次(!).
6 eval {L} line 38 expected 38
7 eval {L} line 39 expected 39
街区
eval
有趣的是,效果很好。不过,也不短
比
_线条__
.
8 eval L line 1 expected 40 *
9 eval L line 1 expected 41 *
弦
埃瓦
在
埃瓦
(不足为奇)
10 my_eval L line 45 expected 42 *
11 my_eval L line 45 expected 43 *
my_eval()
是一个字符串
埃瓦
加一
#line
指令基于
呼叫者
. 它还会在文件后面给出一个行号(!).
12 L2{} line 45 expected 44 *
13 L2{} line 45 expected 45
L2
与
L
但它需要一个返回列表的块,
而不是
列表本身。它还使用
呼叫者
用于行号。而且它
一次正确,但不是两次(!)(可能是因为它是最后一个
项目-
我的评估
报告第45行。)
所以,
这是怎么回事?我听说过去舞会,不知道这是不是
优化相关,但我对引擎的了解不够
从哪里开始调查。我也认为这可以通过源代码实现。
过滤器或
Devel::Declare
但是那远远超出了我的范围
经验水平。
取2
@Zdim的回答让我开始思考流畅的界面,例如
my answer
:
$testcases2 # line 26
->add(__LINE__,0,27,'LINE')
->add(__LINE__,1,28,'LINE')
->L(2,29,'L()')
->L(3,30,'L()')
->L(3,31,'L()')
;
但是,即使这些在这里也不起作用-我得到了26行
->L()
电话。所以看起来
呼叫者
将所有链接的呼叫视为来自
$testcases2->...
行。哦,好吧。我仍然有兴趣知道为什么,如果有人能启发我!