Получение аргументов Классы вызова функции «После удаления» - PullRequest
0 голосов
/ 04 ноября 2018

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

chkArgs <- function() {

    # Get args of the function that called this function
    # stackoverflow.com/q/17256834/633251
    args <- as.list(match.call(definition = sys.function(-1),
        call = sys.call(-1)))[-1]

    print(data.frame(cls = unlist(lapply(args, class)))) # for debugging only

    if (class(eval(args[["x"]])) != "integer")
        stop ("Argument 'x' was not an integer or not found")
    if (class(eval(args[["y"]])) != "integer")
        stop ("Argument 'y' was not an integer or not found")
}

Эта функция работает, как и ожидалось, с помощью этой тестовой функции:

testFunc <- function(x = 1L, y = 1L){ chkArgs(); x + y }

и эти звонки:

testFunc(1L, 1L)
testFunc(3.0, 1L)
testFunc(x = 8L)

Теперь, если мы вызываем chkArgs косвенно или «после удаления», как показано ниже:

testFunc2 <- function(x = 1L, y = 1L){
    chkArgs()
    testFunc(x, y) # also calls chkArg
}

testFunc2(1L, 1L)

Мы получаем этот вывод:

> testFunc2(1L, 1L)
      cls
x integer
y integer
   cls
x name
y name
Error in eval(args[["x"]]) : object 'x' not found

Как я могу заставить chkArgs работать косвенно?

1 Ответ

0 голосов
/ 04 ноября 2018

Вы можете разрешить формальные аргументы родительской функции n увеличивает цепочку вызовов с помощью

fargs <- function(n) { mget(names(formals(sys.function(n))), sys.frame(n), inherits=TRUE); }

Так что ваш chkArgs может быть написано

chkArgs <- function() {

    args <- fargs(-2);  # 2 because the helper function fargs is yet another level down

    if (class(args$x) != "integer")
        stop ("Argument 'x' was not an integer or not found")
    if (class(args$y) != "integer")
        stop ("Argument 'y' was not an integer or not found")

    return(args);
}

Оба случая теперь проверяются.

Основная проблема, как первоначально было написано, заключается в том, что внутренняя проверка просто видит x и y как символы, потому что это то, чем они являются в непосредственной близости от eval. Использование mget с inherits будет искать кадры до тех пор, пока значение не будет разрешено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...