2015-07-01 2 views
3

Я использую пакет R assertthat и хочу (временно) выводить предупреждение вместо ошибки при ошибке утверждения. Какой самый простой способ сделать это с помощью пакета assertthat?Предупреждения вместо ошибок от assert_that()?

Я понимаю, что нежелание предупреждать, а не ошибки, противоречит тому, какие утверждения должны использоваться. В долгосрочной перспективе мы действительно хотим выводить ошибки при ошибке утверждения. В краткосрочной перспективе мы по-прежнему хотим, чтобы код функционировал даже с плохим вводом, так как вывод с плохими входами пока остается «достаточно хорошим».

Простой пример: предположим, что у меня есть функция, которая принимает x как входной сигнал и выдает x + 5. Я хочу вывести предупреждение, если x! = 3. Поскольку мы будем использовать assert_that в конечном счете, было бы неплохо, если бы мы могли использовать assertthat для предупреждения.

В долгосрочной перспективе, мы будем использовать это:

> x <- 3 
> fn <- function(x) {assert_that(x==3); return(x+5)} 
> fn(3) 
[1] 8 
> fn(4) 
Error: x not equal to 3 

В краткосрочной перспективе, вот лучшее, что я до сих пор:

> fn <- function(x) {if(!see_if(x==3)) warning(validate_that(x==3)); return(x+5)} 
> fn(3) 
[1] 8 
> fn(4) 
[1] 9 
Warning message: 
In fn(4) : x not equal to 3 

Я ищу более кратким решение, если это возможно (лучший случай - передать параметр output_warning для assert_that, но я не думаю, что это существует).

ответ

2

Я создал пользовательскую функцию, которая принимает строку, соответствующую выражению, против которого вы хотите запустить validate_that() (в конечном счете assert_that()). Функция выводит предупреждение, если утверждение терпит неудачу и в то же время остается тихим. См. Ниже для использования. Вы можете легко расширить эту настраиваемую функцию, чтобы при необходимости принять более одного выражения. Обратите внимание, что я также использую sys.calls(), чтобы получить имя функции, называемой этой вспомогательной функцией. Это важная часть информации, поэтому вы можете соотнести свои предупреждения с кодом, который их создал.

assert_that_soft <- function(exp) { 
         if (!exp) { 
          print (paste("Error in function:", 
            parse(sys.calls()[[sys.nframe()-1]]))) # name of caller 
         } 
        } 

Использование:

> fn <- function(x) { assert_that_soft(x==3); return(x+5) } 
> fn(3) 
[1] 8 
> fn(8) 
[1] "Error in function: fn(8)" 
[1] 13 
0

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

assert_that <- function(..., env=parent.frame()) { 
    res <- see_if(..., env=env) 
    if (res) 
     return(TRUE) 
    warning(attr(res, "msg")) 
    TRUE 
} 

fn <- function(x) { assert_that(x==3); return(x+5) } 
fn(3) 
# [1] 8 
fn(8) 
# [1] 13 
# Warning message: 
# In assert_that(x == 3) : x not equal to 3 
Смежные вопросы