Назначение с помощью call () - PullRequest
5 голосов
/ 21 января 2020

Предположим, я хочу манипулировать телом функции следующим образом:

> f1 = function(a, b, d) {
+   stop("This is a template!")
+   result
+ }
> body(f1)[[2]] = call("<-", as.name("result"), lapply(letters[1:2], as.name))

Это выглядит хорошо ...

> f1
function (a, b, d) 
{
    result <- list(a, b)
    result
}

... но не работа:

> f1(a = 123, b = 456, d = 999)
[[1]]
a

[[2]]
b

С другой стороны, когда я делаю это:

> body(f1)[[2]] = call("<-", as.name("result"),
+                      as.call(c(as.name("list"), lapply(letters[1:2], as.name))))

Это выглядит то же самое ...

> f1
function (a, b, d) 
{
    result <- list(a, b)
    result
}

... но это работает:

> f1(a = 123, b = 456, d = 999)
[[1]]
[1] 123

[[2]]
[1] 456

Может кто-нибудь разбить это для меня на несколько действительно маленьких кусочков и объяснить, что именно здесь происходит?

1 Ответ

4 голосов
/ 21 января 2020

Проблема в том, что deparse не идеален. Между прочим, это не связано с назначением; та же проблема существует, когда выражение используется в другом контексте, например:

bquote(1 + .(lapply(letters[1:2], as.name)))

или

bquote(sum(.(lapply(letters[1:2], as.name))))

В любом случае вы создаете список имен, но вы не построение вызова list внутри неоцененного выражения. Но (я предполагаю, что) депарсер R не знает, что делать со списком имен в выражении, поскольку такая ситуация не может возникнуть в реальном коде R, который не создан с помощью неоцененных выражений.

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