如何唯一标识函数的所有调用?

时间:2010-06-25 13:08:09

标签: perl perl-xs

我知道caller会给我一个调用函数的文件名和行号,但是如何获得字符或字节偏移?如果我必须为它下拉到XS是可以的(无论如何,该功能可能会成为XS。)

我想要做的是唯一地识别对函数的所有调用,因此,如果在源中有比位置更好的方法,我对其他路径开放。

基本意图是创建一个each函数,可以安全地迭代相同的哈希。这是一个纯粹的Perl版本,类似于我的想法:

#!/usr/bin/perl

use 5.012;
use warnings;
use Scalar::Util qw/refaddr/;

sub safe_each(\%) {
    my $h    = shift;
    my $key  = join "/", (caller)[1,2], refaddr $h;
    state %iter;

    unless (exists $iter{$key}) {
        $iter{$key} = [ keys %$h ];
    }

    unless (@{$iter{$key}}) {
        delete $iter{$key};
        return;
    }

    my $cur = shift @{$iter{$key}};

    return wantarray ? ($cur, $h->{$cur}) : $cur;
}

my %h = (a => 1, b => 2);
while (my ($k, $v) = safe_each %h) {
    say "$k => $v";
    while (my ($k, $v) = safe_each %h) {
        say "\t$k => $v";
    }
}

1 个答案:

答案 0 :(得分:1)

perl调试器将所需的所有源文件行加载到条目

下的主符号表中
@::{"_<$path_to_file"}

这样,当您在文件 FILE 中的 LINE 行到达断点时,调试器可以显示您要执行的代码行:

$::{"_<FILE"}[LINE]

但您也可以使用此信息计算源文件中的当前字符偏移量。

sub _get_offset_into_file {
    my ($file,$line) = @_;
    my *teh_codez = @::{"_<$file"};

    my $offset = 0;
    # the debugger spoofs line $teh_codez[0], so don't include it in offset calc
    $offset += length $_ for @teh_codez[1 .. $line-1];
    return $offset
}

您可以在调试器下运行代码,也可以模拟调试器的功能并自行将文件加载到内存中(然后您不必使用相同的“_&lt;”+文件名约定,甚至可以使用符号完全没有表格。

很抱歉,如果这是一个完全不同的问题的答案,而不是你要问的问题。