Функции Mask R message
, warning
и stop
в PEcAn.logger
выглядят следующим образом:
message <- PEcAn.logger::logger.info
warning <- PEcAn.logger::logger.warn
stop <- PEcAn.logger::logger.severe
И начните заменять все вхождения PEcAn.logger::logger.*
собственными функциями R. В конце концов, мы можем переместить PEcAn.logger
в Suggests
.
Это будет означать, что загрузка PEcAn.logger
в сеансе (с library(PEcAn.logger)
) вызовет подстановку функций — в противном случае выполняющийся код по умолчанию будет использовать стандартные функции обмена сообщениями R.
Несколько причин:
PEcAn.logger::logger.*
— это длинно и неудобно печатать.PEcAn.logger
вводит еще одну не-CRAN-зависимость для каждого из наших пакетов, что делает их более раздражающими при использовании независимо от PEcAn.testthat
expect_error
и т. д.suppressWarnings
или suppressMessages
message
, warning
или stop
, поскольку они используют собственное внутреннее пространство имен пакета.
См. выше (каждый из них должен быть #' @export
-ed. Кроме того, регулярное выражение grepl
в PEcAn.logger
необходимо настроить, чтобы игнорировать warning
, message
и stop
, чтобы оставаться информативными.
Основная причина заключалась в том, что это был способ легко собирать сообщения в файл. Как это сделать с сообщением, предупреждением и остановкой?
Таким образом, все ведение журнала будет работать так же, как и сейчас, если загружен пакет PEcAn.logger
. Просто использование функций ведения журнала больше не требуется. По сути, я предлагаю следующее:
# These call the default R functions
message("hello")
warning("whoops")
stop("whoah")
library(PEcAn.logger)
# By loading the logger package, the functions become masked so
message("hello") # This actually calls `PEcAn.logger::logger.info
warning("whoops") # This calls `PEcAn.logger::logger.warn
stop("error") # This calls `PEcAn.logger::logger.severe
Так что все те же функции по настройке уровня логгера, выходного файла и т.п. должны работать одинаково.
Кстати, message
, warning
и stop
базы R могут быть выборочно перенаправлены через sink
.
Если имена слишком длинные: я бы предпочел экспортировать псевдонимы, которые удаляют избыточную часть logger.*
, например, PEcAn.logger::info()
. Все, что выходит за рамки этого, возвращается к спору о пространствах имен и вызовах library
.
Что касается неловкости с такими функциями, как expect_error
или suppressMessages
: большое основное различие здесь заключается в том, что PEcAn.logger не использует формальный механизм сигнализации условий R, и поэтому его неудобно использовать с любой функцией. который ожидает condition
. Если PEcAn.logger можно переделать для использования условий, я бы предпочел это сделать, но я также не знаком с историей здесь - @robkooper избегал signalCondition
преднамеренного выбора дизайна / необходимого для обработки некоторые случаи перенаправления?
Подумав об этом еще немного, я согласен, что мой подход не имеет смысла и на самом деле не будет работать. Лично я, вероятно, предпочел бы использовать функции R по умолчанию ( stop
, warning
, message
), перенаправляя их через sink
при необходимости, но я вижу причина придерживаться PEcAn.logger
. Другая возможность — переключиться на futile.logger
, что было предложено ранее (#1362).
А пока мне нравятся оба предложения @infotroph — добавление более коротких псевдонимов и условий сигнализации.
Другой многообещающей идеей является пакет debugme
с таким синтаксисом:
f <- function(a, b = 3) {
c <- a + b
d <- a * b
e <- a ^ b
"!DEBUG arguments are a = `a` and b = `b`"
c(c, d, e)
}
Эта проблема устарела, потому что она была открыта 365 дней без каких-либо действий.
См. также обсуждение в #1362.
Самый полезный комментарий
Если имена слишком длинные: я бы предпочел экспортировать псевдонимы, которые удаляют избыточную часть
logger.*
, например,PEcAn.logger::info()
. Все, что выходит за рамки этого, возвращается к спору о пространствах имен и вызовахlibrary
.Что касается неловкости с такими функциями, как
expect_error
илиsuppressMessages
: большое основное различие здесь заключается в том, что PEcAn.logger не использует формальный механизм сигнализации условий R, и поэтому его неудобно использовать с любой функцией. который ожидаетcondition
. Если PEcAn.logger можно переделать для использования условий, я бы предпочел это сделать, но я также не знаком с историей здесь - @robkooper избегалsignalCondition
преднамеренного выбора дизайна / необходимого для обработки некоторые случаи перенаправления?