gpt4 book ai didi

r - env_parent() : different results when using default argument or when passing explicitly default argument

转载 作者:行者123 更新时间:2023-12-05 05:49:43 24 4
gpt4 key购买 nike

我注意到使用 rlang 包中的 env_parent() 和使用 env_parent(caller_env()) 时有不同的行为,尽管 caller_env()env_parent() 第一个参数的默认参数:

library(rlang)
env_parent
#> function (env = caller_env(), n = 1)
#> {
#> env_ <- get_env_retired(env, "env_parent()")
#> while (n > 0) {
#> if (is_empty_env(env_)) {
#> abort("The empty environment has no parent")
#> }
#> n <- n - 1
#> env_ <- parent.env(env_)
#> }
#> env_
#> }
#> <bytecode: 0x000000001d8ad000>
#> <environment: namespace:rlang>

我对环境不是很熟悉,我只能基于 Shiny 的应用程序准备 MRE(我已经注意到使用 Shiny 的应用程序)。将应用程序放在两个文件中很重要 - ui.Rserver.R:

ui.R

library(shiny)
library(rlang)

parent <<- function() {
env_parent()
}

parents_default_arg_passed <<- function() {
env_parent(caller_env())
}

ui <- fluidPage(
textOutput("env_parent"),
textOutput("env_parents_default_arg_passed")
)

server.R

server <- function(input, output, session) {

output$env_parent <- renderPrint({
names(parent())
})

output$env_parents_default_arg_passed <- renderPrint({
names(parents_default_arg_passed())
})

}

我在运行应用程序后看到了这个输出:

[1] "ui"
[1] "~" ".__tidyeval_quosure_mask__."

这是为什么?

最佳答案

对您的问题的简短回答是,显式调用带参数的函数与调用函数并让它自己提供与默认值相同的参数相比是有区别的。在后一种情况下,调用者环境是函数的执行环境。在前一种情况下,调用者环境是函数被显式调用的地方。

我花了一段时间才找到对正在发生的事情的一个很好的可视化,但我想我找到了一个。

让我们创建两个类似于 {rlang} 的 env_parentcaller_env 的函数。不同的是,myCallEnv 不仅会返回调用函数的执行环境,它还会用lobstr::cst()显示调用轨迹树:

myCallEnv <- function() {
print(lobstr::cst())
caller_env(n = 1)
}

myEnvParent <- function(e = myCallEnv()) {
env_parent(env = e)
}

现在让我们用默认参数调用 myEnvParent 一次,然后显式提供相同的默认参数调用一次:

myEnvParent()
# ▆
# 1. └─global myEnvParent()
# 2. ├─rlang::env_parent(env = e)
# 3. │ └─rlang:::get_env_retired(env, "env_parent()")
# 4. │ └─rlang::is_environment(x)
# 5. └─global myCallEnv()
# 6. ├─base::print(lobstr::cst())
# 7. └─lobstr::cst()
# NULL
# <environment: R_GlobalEnv>

myEnvParent(myCallEnv())
# ▆
# 1. ├─global myEnvParent(myCallEnv())
# 2. │ └─rlang::env_parent(env = e)
# 3. │ └─rlang:::get_env_retired(env, "env_parent()")
# 4. │ └─rlang::is_environment(x)
# 5. └─global myCallEnv()
# 6. ├─base::print(lobstr::cst())
# 7. └─lobstr::cst()
# NULL
# <environment: package:rlang>
# attr(,"name")
# [1] "package:rlang"
# attr(,"path")
# [1] # "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/rlang"

比较两个输出我们可以看到,在第一次调用 myEnvParent() 时,myCallEnv() 是从 myEnvParent()< 的执行环境调用的。父环境是全局环境 R_GlobalEnv

在第二次调用中,myEnvParent(myCallEnv())myCallEnv() 是从全局环境调用的,因此它的父级是搜索路径上的第二个环境:

searchpaths()
# [1] ".GlobalEnv"
# [2] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/rlang"
# [3] "tools:rstudio"
# [4] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/stats"
# [5] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/graphics"
# [6] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/grDevices"
# [7] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/utils"
# [8] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/datasets"
# [9] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/methods"
#[10] "Autoloads"
#[11] "/Library/Frameworks/R.framework/Resources/library/base"

关于r - env_parent() : different results when using default argument or when passing explicitly default argument,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70626136/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com