如何让全局环境中定义的函数访问其调用函数环境中定义的变量?

时间:2018-09-05 14:59:13

标签: r plumber

 // check header or url parameters or post parameters for token
  const token = req.body.token || req.query.token || req.headers['x-access-token'] || req.headers['Authorization'] || req.headers['Bearer'];

错误消息:

connect_dw <- function() {
  DBI::dbConnect(RSQLite::SQLite(), ":memory:")
}

fetch_sql_res <- function(key, ...) {
  query_list <- list(...)
  query_sql_res <- function(.query_list = query_list, .db_connect_f = connect_dw) {
    con <- .db_connect_f()
    res <- purrr::map(.query_list, glue::glue_sql, .con = con ) %>%
      purrr::map(purrr::partial(DBI::dbGetQuery, conn = con))
    DBI::dbDisconnect(con)
    res
  }

 ## if key exists in redis cache, fetch it from redis.
 ## If not, call the function to query database

  query_sql_res()

}

#' testing
#' @serializer unboxedJSON
#' @get /test_db
test_db <- function() {
  userid <- 10

  fetch_sql_res(df = "SELECT {userid}")
}

我想创建一个可以在函数内部使用的函数(该函数用于使用管道工创建Web api)。

该函数用于获取sql结果。需要一些变量来构造sql查询。

上面的代码不起作用。看来问题出在环境方面。

1 个答案:

答案 0 :(得分:3)

所有R函数都具有词法范围,这意味着它们从定义函数的地方继承变量,而不是从调用地方继承。您无法更改此默认行为,因为它会破坏很多事情。因此,在评估需要不同环境的函数调用时,只需要小心指定正确的环境即可。

在这种情况下,问题似乎在于glue::glue_sql无法找到变量。该函数具有一个.envir=参数,该参数告诉它在哪里寻找变量。您只需要明确地将调用环境传递给该函数。例如

fetch_sql_res <- function(key, ...) {
  query_list <- list(...)
  calling_env <- parent.frame()
  query_sql_res <- function(.query_list = query_list, .db_connect_f = connect_dw) {
    con <- .db_connect_f()
    res <- purrr::map(.query_list, glue::glue_sql, .con = con, .envir=calling_env ) %>%
      purrr::map(purrr::partial(DBI::dbGetQuery, conn = con))
    DBI::dbDisconnect(con)
    res
  }
  query_sql_res()
}

这不是“通用”解决方案,但相同的基本思想将在其他地方应用。您需要在需要时明确引用调用环境。