2

我知道这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";
    }
}
4

1 回答 1

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
}

您可以在调试器下运行代码,也可以模拟调试器所做的并将文件自己加载到内存中(这样您就不必使用相同的“_<”+文件名约定,甚至根本不需要使用符号表)。

抱歉,如果这是对与您所问问题完全不同的问题的答案。

于 2010-06-25T18:08:38.363 回答