Как обратный вызов SVN :: Error может идентифицировать контекст, из которого он был вызван? - PullRequest
3 голосов
/ 14 апреля 2010

Я написал несколько довольно обширных модулей и сценариев Perl, используя привязки Perl SVN :: Client и т. Д. Поскольку все вызовы SVN :: Client глубоко в модуле, я переопределил значение по умолчанию обработка ошибок.

Пока что я сделал это, установив

$SVN::Error::handler = undef;

, как описано в документации , но это делает отдельные вызовы немного беспорядочными, потому что вы должны помнить, чтобы каждый вызов SVN::Client выполнялся в контексте списка и проверял первое значение на наличие ошибок.

Я хотел бы перейти на использование обработчика ошибок, который я написал бы; но $SVN::Error::handler является глобальным, поэтому я не вижу, чтобы мой обратный вызов мог определить, откуда возникла ошибка и в каком объекте установить код ошибки.

Мне было интересно, могу ли я использовать пул для этой цели: до сих пор я игнорировал пулы как не относящиеся к работе в Perl, но если я вызову SVN::Client метод с созданным мною пулом, будет ли SVN :: Ошибка объект будет создан в том же пуле?

Кто-нибудь имеет какие-либо знания или опыт, которые имеют отношение к этому?

1 Ответ

1 голос
/ 17 мая 2010

ОК, я собираюсь предположить, что проблема в том, что (а) вы хотите установить флаг в каком-либо объекте при возникновении ошибки, а затем проверить флаг позже в конце всех операций, и (б) что ваш обработчик ошибок (в глобальной переменной) должен каким-то образом узнать, к какому объекту обращаться. Вы можете достичь этого с помощью замыкания, например:

#
# This part is the library that implements error handling a bit like
# SVN::Client
#
sub default_error_handler {
  croak "An error occurred: $_[0]";
}

our $global_error_handler = \&default_error_handler;

sub library_function_that_might_fail {
  &$global_error_handler("Guess what - it failed!");
}

#
# This part is the function that wants to detect an error
#
sub do_lots_of_stuff {
  my $error = undef; # No errors so far!

  local($global_error_handler) = sub { $error = $_[0]; };

  library_function_that_might_fail();
  library_function_that_might_fail();
  library_function_that_might_fail();

  if ($error) {
    print "There was an error: $error\n";
  }
}


#
# Main program
#
do_lots_of_stuff();

Ключ заключается в том, что когда в do_lots_of_stuff() мы устанавливаем обработчик ошибок на анонимную подпрограмму, эта подпрограмма продолжает иметь доступ к локальным переменным функции, которая ее создала, поэтому она может изменять $error, чтобы сигнализировать что произошла ошибка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...