Как получить точный caller() в Mojolicious?

Вопрос или проблема

Как мне настроить стековый трейс Mojolicious так, чтобы он отображал физический исходный код?

Например, при выполнении приведенного ниже кода:

/foo/bar/app.pl:

 1 #!/usr/bin/env perl
 2 use Mojolicious::Lite;
 3
 4 get "https://stackoverflow.com/" => sub {
 5   my $c = shift;
 6
 7   my ($package, $filename, $line, $subroutine, $hasargs, $wantarray,
 8     $evaltext, $is_require, $hints, $bitmask, $hinthash) = caller(0);
 9
10   $c->render(text =>
11     'p=' . $package    . ',' .
12     'f=" . $filename   . ",' .
13     'l=" . $line       . ",' .
14     'm=' . $subroutine
15   );
16 };
17
18 app->start;

Фактический результат:

# /foo/bar/app.pl daemon

p=Mojolicious,f=/usr/local/share/perl5/Mojolicious.pm,l=202,m=main::__ANON__

# morbo /foo/bar/app.pl

p=Mojolicious,f=/usr/local/share/perl5/Mojolicious.pm,l=202,m=Mojo::Server::Sandbox::b89e17a47746799cd9250564e1c58531::__ANON__

Ожидаемый результат:

f=/foo/bar/app.pl
l=7
m=main::__ANON__

Ответ или решение

Для того чтобы получить точную информацию о вызове в Mojolicious, необходимо учитывать, что при использовании morbo или daemon происходит выполнение кода в контексте другого пакета, что может привести к получению неверного значения для $filename, $line и $subroutine при вызове функции caller().

Чтобы достичь ожидаемого поведения и отобразить физический код вашего приложения, вы можете использовать следующий подход:

Решение:

  1. Использование caller(1): Измените вызов caller(0) на caller(1), чтобы он ссылался на уровень вызова выше, что должно вернуть правильные значения, когда вы находитесь в контексте хендлера.

  2. Проверка контекста: Нужно удостовериться, что код действительно выполняется в контексте вашего приложения, а не в рамках модуля Mojolicious.

Пример кода:

#!/usr/bin/env perl
use Mojolicious::Lite;

get "https://stackoverflow.com/" => sub {
  my $c = shift;

  # Используем caller(1) для получения информации о вызывающем коде
  my ($package, $filename, $line, $subroutine) = caller(1);

  $c->render(text =>
    'p=' . $package     . ',' .
    'f="' . $filename   . '",' .
    'l=' . $line       . ',' .
    'm=' . $subroutine
  );
};

app->start;

Объяснение:

  • При изменении caller(0) на caller(1), мы обращаемся к информации о вызывающем уровне, который в данном случае будет соответствовать вашему хендлеру.
  • Эта модификация позволит отобразить правильный файл (/foo/bar/app.pl), строку (7) и имя подпрограммы (например, main::__ANON__), что и требуется для получения ожидаемого результата.

Итоги:

С помощью предложенной модификации, ваше приложение Mojolicious сможет отражать точную информацию о вызовах из вашего исходного кода. Не забудьте протестировать свою реализацию после внесения изменений, чтобы убедиться, что вся необходимая информация отображается корректно.

Оцените материал
Добавить комментарий

Капча загружается...