Предполагая, что если a
является логическим NA, тогда оно все равно должно вернуть 0, тогда попробуйте это (или замените вторую строку тела на a * b
, если логический NA для a
) должен вернуть НС).
В любом случае, главное, что следующий стиль stopifnot
можно использовать для проверки аргументов.
func2 <- function(a, b) {
stopifnot(is.logical(a), is.numeric(b))
isTRUE(a) * b
}
func2(TRUE, 3)
## [1] 3
func2(9, 2)
## Error in func2(9, 2) : is.logical(a) is not TRUE
Вместо stopifnot
используйте if (...) stop(...)
, по одному такому утверждению на аргумент, если вам нужны пользовательские сообщения об ошибках.
Обратите внимание, что можно использовать S3 для отправки в метод на основе первого аргумента или S4 для отправки в данную сигнатуру. Если метод для такой подписи не существует, будет вызвана ошибка.
Вот пример S4:
setMethod("func3", c("logical", "numeric"), function(a, b) isTRUE(a) * b)
func4(TRUE, 3)
## [1] 3
func4(2, 1)
## Error in UseMethod("func3") :
## no applicable method for 'func4' applied to an object of class "c('double', 'numeric')"
Вот пример S3:
# check 1st arg using S3 dispatch and 2nd arg using stopifnot
func3 <- function(a, b) UseMethod("func4")
func3.logical <- function(a, b) {
stopifnot(is.numeric(b))
isTRUE(a) * b
}
func3(TRUE, 3)
## [1] 3
func3(3, 8)
## Error in UseMethod("func3") :
## no applicable method for 'func3' applied to an object of class "c('double', 'numeric')"
В CRAN есть пакет с именем checkmate для проверки аргументов, которая используется довольно многими другими пакетами (заменяя ныне несуществующий пакет ArgumentCheck ). Другой пакет для проверки типа аргументов - TypeInfo на Bioconductor.
Существует пакет под названием rtype для строгой проверки типов.
Также есть пакеты assertive.types , assertive , assertr , assertable и assertthat для типа утверждения.
Также отметим, что в отношении кода в вопросе, что класс S3 является вектором и может иметь более одного элемента, используйте is.someclass
(если такая функция существует для someclass
) или inherits(X, "someclass")
, где [1112 ] интересующий класс, а не class(X) == "someclass"
для проверки классов S3.
По какой-то причине событие Application_Error не запускается для веб-служб (см. другой вопрос ). Сам г-н Джефф Этвуд опубликовал несколько советов в блоге ужасов кодирования .
Он пишет:
* Попробуйте ... поймайте каждый метод WebService. Эти методы, как правило, являются оболочками для других классов, так что это не так плохо, как кажется, но все же не хорошо.
* использовать шаблон проектирования фасада для получения всех объектов из родительских объектов, которые .. в основном выполняют try..catch для метода .Execute. Спасибо, но нет, спасибо.
* Напишите собственное расширение SOAP или HttpModule. Звучит разумно, но ... сложно. Если это такое классное, важное расширение или HttpModule, разве кто-нибудь не написал бы его?
Один из способов - подписаться на событие AppDomain.UnhandledException
где-нибудь в обработчике App_Start
.