Я знаю, что caller
даст мне имя файла и номер строки, где была вызвана функция, но как я могу получить смещение символа или байта?Ничего страшного, если я должен перейти к XS для этого (функция, вероятно, все равно окажется XS).
Я пытаюсь однозначно идентифицировать все вызовы функции, поэтому, еслиесть метод лучше, чем location в источнике, я открыт для других маршрутов.
Основное назначение - создать функцию 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";
}
}