使用glue::glue时处理命名空间的更好方法

Posted

技术标签:

【中文标题】使用glue::glue时处理命名空间的更好方法【英文标题】:Better way to deal with namespace when using glue::glue使用glue::glue时处理命名空间的更好方法
【发布时间】:2020-06-20 12:33:04
【问题描述】:

我想创建一个函数,它本身使用了很棒的glue::glue 函数。

但是,当我想粘合一个存在于函数和全局环境中的变量时,我发现自己正在处理一些命名空间问题:

x=1

my_glue <- function(x, ...) 
    glue::glue(x, ...)

my_glue("foobar x=x") #not the expected output
# foobar x=foobar x=x

为了包的一致性,我宁愿保留名为 x 的变量。

我最终做了这样的事情,到目前为止效果很好,但只是推迟了问题(很多,但仍然):

my_glue2 <- function(x, ...) 
    x___=x; rm(x)
    glue::glue(x___, ...)

my_glue2("foobar x=x") #problem is gone!
# foobar x=1
my_glue2("foobar x=x___") #very unlikely but still...
# foobar x=foobar x=x___

有没有更好/更清洁的方法来做到这一点?

【问题讨论】:

@RonakShah 抱歉,复制粘贴错误 但是你没有在函数中传递值x = 1。您希望它如何进入功能?为什么不传递它是一个单独的参数? 你说得对,这不是很清楚。我希望我的函数始终使用调用环境的 x 变量,而不是保存整个字符串的 x 参数
【参考方案1】:

由于值 x = 1 没有传递给函数,在当前场景中,这样做的一种方法是评估全局环境中的字符串,其中存在 x 的值,然后再将其传递给功能。

my_glue(glue::glue("foobar x=x"))
#foobar x=1

my_glue(glue::glue("foobar x=x"), " More text")
#foobar x=1 More text

另一种选择(我认为这是您正在寻找的答案)是从父环境中获取 x 的值。 glue 具有 .envir 参数,可以在其中定义评估表达式的环境。

my_glue <- function(x, ...) 
   glue::glue(x, ...,.envir = parent.frame())

my_glue("foobar x=x")
#foobar x=1

【讨论】:

我想你会想使用.envir = parent.frame()而不是硬编码.GlobalEnv @TylerSmith 是的,一个更好的选择。更新了答案。 太棒了,谢谢。确实,第一个选项不是我想要的,并且使整个功能变得毫无用处。不过我很惊讶,.envir = parent.frame() 不是 glue 的默认值吗? 是的,我最初也是这么想的,因此我硬编码了.GlobalEnv。事实证明它不是这样工作的。奇怪。

以上是关于使用glue::glue时处理命名空间的更好方法的主要内容,如果未能解决你的问题,请参考以下文章

在 PINIA、Vue 3+Typescript 上处理命名空间模块化方法

XML名命空间

为啥要使用 __prepare__ 方法来获取类的命名空间?

有没有办法在创建项目时设置项目的默认命名空间?

命名空间和类名冲突

C++命名空间应用