这是部分答案。x
首先,如果您在内部匿名函数的调用环境中进行评估,则很容易使其工作,
library(magrittr)
f <- function(x) { x; function(y) x + y }
f.5 <- 5 %>% f
6 %>% f.5
# [1] 11
要调查出了什么问题,请查看x
正在评估的内容,
f <- function(x) {
function(y) {
print(sprintf("x: %s.", toString(x)))
x + y
}
}
## the failing case
fails <- 5 %>% f
6 %>% fails
# [1] "x: function (y) \n{\n print(sprintf(\"x: %s\", toString(x)))\n x + y\n}, TRUE"
它指向调用withVisible
on的结果f
,这在调用函数时发生freduce
(代码)。在pipe
函数体中,有一行,
body(magrittr:::pipe)[[2]][[3]][[10]]
# env[["freduce"]] <- freduce
在哪里freduce
可用(查看magrittr:::pipe
完整的上下文)。
如果将这一行修改为函数中的实际代码freduce
(即复制magrittr:::freduce
),它似乎可以工作,
## Make a modified %>% operator
mypipe <- magrittr:::pipe
## Change that line
body(mypipe)[[2]][[3]][[10]] <- quote(
env[["freduce"]] <-
function(value, function_list) {
k <- length(function_list)
if (k == 1L) {
result <- withVisible(function_list[[1L]](value))
if (result[["visible"]])
result[["value"]]
else
invisible(result[["value"]])
} else {
Recall(function_list[[1L]](value), function_list[-1L])
}
}
)
## Redefine
`%>%` <- mypipe()
## Test (now it works?!)
fails <- 5 %>% f
6 %>% fails
# [1] "x: 5"
# [1] 11
所以,这是一个部分解决方案,因为我无法弄清楚为什么freduce
以这种方式重新定义它会起作用。