簡體   English   中英

如何讓全局環境中定義的函數訪問其調用函數環境中定義的變量?

[英]How to let function defined in global environment access variables defined in its calling function's environment?

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}")
}

錯誤信息:

 Error in eval(parse(text = text, keep.source = FALSE), envir) : 
  object 'userid' not found

我想創建一個可以在一個函數內使用的函數(該函數用於使用管道工創建Web api)。

該函數用於獲取sql結果。 它需要一些變量來構造sql查詢。

上面的代碼不起作用。 看來問題出在環境上。

所有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()
}

這不是“通用”解決方案,但相同的基本思想將在其他地方應用。 您需要在需要時顯式引用調用環境。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM