如何唯一标识对函数的所有调用?
我知道 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";
}
}
I know that caller
will give me the file name and line number where a function was called, but how can I get the character or byte offset? It is okay if I must drop down to XS for it (the function will probably wind up being XS anyway).
What I am trying to do is uniquely identify all of the calls to a function, so, if there is a better method than location in the source, I am open to other routes.
The basic intent is to make an each
function that can safely iterate over the same hash. Here is a pure Perl version that is similar to what I am thinking about:
#!/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";
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Perl 调试器将其需要的源文件的所有行加载到条目下的主符号表中。
这样,当您到达文件 FILE 中行 LINE 处的断点时,调试器可以显示您将要执行的代码行:
但您也可以使用此信息来计算源文件中的当前字符偏移量。
您可以在调试器下运行代码,或者模拟调试器的功能并自己将文件加载到内存中(这样您就不必使用相同的“_<”+文件名约定,甚至根本不需要使用符号表) )。
抱歉,如果这是一个与您所问的问题完全不同的问题的答案。
The perl debugger loads all lines of the source files that it needs into the main symbol table under the entry
This way when you reach a breakpoint at line LINE in file FILE, the debugger can display the line of code you are about to execute:
But you could also use this information to compute the current character offset into your source file.
You could either run your code under the debugger, or emulate what the debugger does and load the files into memory yourself (then you wouldn't have to use the same "_<" + filename convention, or even use the symbol table at all).
Sorry if this is an answer to a completely different question than the one you are asking.