Вызвать полезную ошибку, если я предоставлю неверно названный аргумент - PullRequest
0 голосов
/ 25 февраля 2019

При написании функции, включающей аргумент ..., ошибка в имени аргумента не приведет к немедленной ошибке.это особенно раздражает, когда мы забываем «поставить точку» аргументу

addxy <- function(..., .x, .y, .z){
  .x + .y
}

addxy(.x=1,.y=2)
# [1] 3
addxy(.x=1,y=2)
# Error in addxy(.x = 1, y = 2) : argument ".y" is missing, with no default

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

Как я могу дать дружественную ошибку в этом случае, чтобы помочь пользователю исправить свой звонок?

1 Ответ

0 голосов
/ 25 февраля 2019

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

Собрать все в одинфункция, которую мы получаем:

with_friendly_dot_error <- function(fun){
  fiendly_fun <- fun
  body(fiendly_fun) <- substitute({
    MC <- match.call()
    MC[[1]] <- quote(fun)
    res <- try(eval.parent(MC),silent = TRUE)
    if(inherits(res,"try-error")){
      frmls <- setdiff(names(formals()),"...")
      dot_names <- names(eval(substitute(alist(...))))
      candidates <- intersect(paste0(".",dot_names), frmls)
      stop(attr(res,"condition")$message,
           "\nDid you forget the dots in argument(s): ",
           paste0(candidates, collapse = ", ")," ?")
    }
    res
  })
  fiendly_fun
}

Работает нормально, когда нет ошибок:

with_friendly_dot_error(addxy)(.x=1,.y=2)
# [1] 3

При необходимости выдает полезную ошибку:

with_friendly_dot_error(addxy)(.x=1, y=2)
# Error in with_friendly_dot_error(addxy)(.x = 1, y = 2) : 
#   argument ".y" is missing, with no default
# Did you forget the dots in argument(s): .y ?
...