我知道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";
}
}
答案 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;”+文件名约定,甚至可以使用符号完全没有表格。
很抱歉,如果这是一个完全不同的问题的答案,而不是你要问的问题。