加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何获取测试用例的多行列表初始值设定项中的当前行号?

发布时间:2020-12-16 06:21:38 所属栏目:大数据 来源:网络整理
导读:有没有办法在Perl期间可靠地获取当前行号 没有明确使用__LINE__的多行列表分配?我是 将测试用例存储在列表中,并希望用它的行标记每个测试用例 数字.*那样我可以(粗略地) 对于@tests,确定($_- [1],’line’.$_- [0]). 而且,当然,我想保存打字比较 将__LINE__
有没有办法在Perl期间可靠地获取当前行号
没有明确使用__LINE__的多行列表分配?我是
将测试用例存储在列表中,并希望用它的行标记每个测试用例
数字.*那样我可以(粗略地)
对于@tests,确定($_-> [1],’line’.$_-> [0]).
而且,当然,我想保存打字比较
将__LINE__放在每个测试用例的开头:).我有
找不到办法,我遇到了一些
调用者报告的行中令人困惑的行为.

*可能的XY,但我找不到一个模块来做它.

更新我发现了一个hack并将其发布为an answer.感谢@zdim帮助我以不同的方式思考问题!

MCVE

很长一段,因为我尝试了几种不同的选择. my_eval,
L()和L2 {}是我迄今为止尝试的一些 – L()就是那个
我最初希望能工作.跳到我的@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,&$fn];
} #L2

# List of [line number,item index,expected line number,type]
my @testcases = (
    ([__LINE__,32,'LINE']),([__LINE__,1,33,(L(2,34,'L()')),(L(3,35,(do { L(4,36,'do {L}') }),(do { L(5,37,(eval { L(6,38,'eval {L}') }),(eval { L(7,39,(eval "L(8,40,'eval L')"),(eval "L(9,41,(my_eval("L(10,42,'my_eval L')")),(my_eval("L(11,43,(L2{12,44,'L2{}'}),(L2{13,45,);

foreach my $idx (0..$#testcases) {
    printf "%2d %-10s line %2d expected %2d %sn",$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

使用__LINE__明确地工作正常,但我正在寻找一个
缩写.

2 L()        line 45 expected 34 *
 3 L()        line 45 expected 35 *

L()使用调用者来获取行号,并在以后报告一行
在文件(!)中.

4 do {L}     line 36 expected 36
 5 do {L}     line 45 expected 37 *

当我在do {}中包装L()调用时,调用者返回正确的
行号 – 但只有一次(!).

6 eval {L}   line 38 expected 38
 7 eval {L}   line 39 expected 39

有趣的是,块eval工作得很好.但是,它并不短
比__LINE__.

8 eval L     line  1 expected 40 *
 9 eval L     line  1 expected 41 *

字符串eval给出了eval中的行号(毫不奇怪)

10 my_eval L  line 45 expected 42 *
11 my_eval L  line 45 expected 43 *

my_eval()是一个字符串eval加上一个基于的#line指令
呼叫者.它还在文件后面给出一个行号(!).

12 L2{}       line 45 expected 44 *
13 L2{}       line 45 expected 45

L2与L相同,但它需要一个返回列表的块,
而不是
清单本身.它还使用呼叫者作为行号.它
是正确的,但不是两次(!). (可能只是因为它是最后一次
item – my_eval也报告第45行.)

那么,这里发生了什么?我听说过Deparse并想知道这是不是
优化相关,但我不知道引擎知道
从哪里开始调查.我也想象这可以用来源完成
过滤器或Devel::Declare,但这远远超出我的
经验等级.

拿2

@ zdim的回答让我开始考虑流畅的界面,例如,在my answer:

$testcases2     # line 26
    ->add(__LINE__,27,'LINE')
    ->add(__LINE__,28,'LINE')
    ->L(2,29,'L()')
    ->L(3,30,31,'L()')
;

但是,即使那些在这里不起作用 – 我为每个 – > L()调用得到第26行.因此看起来调用者将所有链接的调用视为来自$testcases2-> …行.那好吧.我仍然有兴趣知道为什么,如果有人可以开导我!

解决方法

调用者只能获得在编译时决定的语句行号.

当我将代码更改为

my @testcases;
push @testcases,'LINE']);
push @testcases,'L()'));
push @testcases,'L()'));
...

保持行号,它有效(除了字符串evals).

因此,在实际方面,使用调用者可以使用单独的调用语句.

在编译时将行号烘焙到op-tree中(我的重点)

At run-time,only the line numbers of statements are available […]

从ikegami’s post on permonks.

我们可以通过运行perl -MO = Concise script.pl来看到这一点

2      nextstate(main 25 line_nos.pl:45) v:*,&,{,x*,x&,x$,$,67108864 ->3

用于nextstate op,它设置调用者(和警告)的行号.见this post.

然后解决这个问题的方法是尝试欺骗编译(“某种程度上”),或者更好的是,不要在这样的列表中组装信息.其中一种方法是在answer by cxw.

有关相关案例和更多详细信息,请参阅this post.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读