R: вспомогательная функция, которая проверяет аргументы в среде - PullRequest
0 голосов
/ 04 июня 2018

В R (3.4.3),

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

Текущий код

foo_add <- function(x, y = x, divisible = TRUE) {

 if(missing(x) || !is.numeric(x)) stop("define x as a number")
 if(!is.numeric(y)) y <- x
 if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")

 ...}


foo_subtract <- function(x, y = x, divisible = TRUE) {

 if(missing(x) || !is.numeric(x)) stop("define x as a number")
 if(!is.numeric(y)) y <- x
 if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")

 ...}


foo_divide <- function(x, y = x, divisible = TRUE) {

 if(missing(x) || !is.numeric(x)) stop("define x as a number")
 if(!is.numeric(y)) y <- x
 if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")

 ...}

Вы видите, что я повторяю код толькочтобы убедиться, что useR правильно определил аргументы.Ниже я добавил возврат списка, чтобы проверить, все ли работает.Моя версия более чистой версии:

Требуемый код

foo_add <- function(x, y = x, divisible = TRUE) {
     do.call("check_args", mget(names(formals())))
     list(x,y,divisible)
   }


foo_subtract <- function(x, y = x, divisible = TRUE) {
     do.call("check_args", mget(names(formals())))
     list(x,y,divisible)
   }


foo_divide <- function(x, y = x, divisible = TRUE) {
     do.call("check_args", mget(names(formals())))
     list(x,y,divisible)
   }

check_args <- function(x,y,divisible) {
     if(missing(x) || !is.numeric(x)) stop("define x as a number")
     if(!is.numeric(y)) y <- x
     if(!is.logical(divisible)) stop("define divisible as TRUE or FALSE")
   }

В основном я хочу всегда проверять, правильно ли заданы действительные аргументы, одновременно контролируя аргументы по умолчаниюи недостающие аргументы.Исходя из своих базовых знаний, я хочу создать функцию конструктора-esk для реальных аргументов.Я также хочу иметь возможность не только проверять ошибки, но и изменять фактические значения аргументов и возвращать их в родительскую функцию для использования (например, как условие if(!is.numeric(y)) y <- x).

Желаемый код, кажется, работает, я просто хочу убедиться, учитывая, насколько я новичок в программировании на R, что я за что-то беру учет.В частности, если я изменяю объекты в check_args(), то передаю их родительской функции, используя do.call. Есть ли более чистый способ сделать это?

...