Как я могу однозначно идентифицировать все вызовы функции? - PullRequest
2 голосов
/ 25 июня 2010

Я знаю, что 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";
    }
}

1 Ответ

1 голос
/ 25 июня 2010

Отладчик perl загружает все необходимые строки исходных файлов в основную таблицу символов под записью

@::{"_<$path_to_file"}

Таким образом, когда вы достигаете точки останова в строке LINE в файле FILE , отладчик может отобразить строку кода, которую вы собираетесь выполнить:

$::{"_<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
}

Вы можете либо запустить код под отладчиком, либо подражать тому, что делает отладчик, и загружать файлы в память самостоятельно (тогда вам не придется использовать то же самое соглашение "_ <" + имя файла, или даже использовать символ стол вообще). </p>

Извините, если это ответ на совершенно другой вопрос, чем тот, который вы задаете.

...