如何编写/覆盖自己的赋值函数,就像`names<-`中那样?

huangapple go评论112阅读模式
英文:

How to write/override your own assignment function as in `names<-`?

问题

受到 names&lt;- 函数工作方式的启发,我想在一个包内实现类似的功能。

可复现示例

创建一个空的包,并添加以下文件:

## R/internal-state.R
the <- new.env(parent = emptyenv())

#' @export
object <- function(name) the[[name]]

#' @export
set_object <- function(name, value) the[[name]] <- value

然后在控制台执行以下步骤:

> usethis::use_namespace() ## 然后选择 Yes
> devtools::document()

之后,使用 CTRL+SHIFT+B 安装包。

现在你可以执行以下操作:

> library(testpackage)
> set_object("foo", 1)
> object("foo")
[1] 1

问题

如何修改这个示例以实现以下功能?

> library(testpackage)
> object("foo") <- 1
> object("foo")
[1] 1

(请注意,上述代码段中的 &quot; 是 HTML 实体,应该被替换为正常的双引号 ",以使代码正常工作。)

英文:

Inspired by the way the names&lt;- function works I want to be able to do something similar inside a package.


Reproducible example

Create an empty package and add the following file:

## R/internal-state.R
the &lt;- new.env(parent = emptyenv())

#&#39; @export
object &lt;- function(name) the[[name]]

#&#39; @export
set_object &lt;- function(name, value) the[[name]] &lt;- value

Then on the console:

&gt; usethis::use_namespace() ## and choose Yes
&gt; devtools::document()

After that, install package with CTRL+SHIFT+B


Now you can do this:

&gt; library(testpackage)
&gt; set_object(&quot;foo&quot;, 1)
&gt; object(&quot;foo&quot;)
[1] 1

Question

How to modify this example to be able to do that?

&gt; library(testpackage)
&gt; object(&quot;foo&quot;) &lt;- 1
&gt; object(&quot;foo&quot;)
[1] 1

答案1

得分: 1

不能使用这样的函数,如果第一个值不是可赋值的。在这里,您有字面字符串值 "foo",您不能对该字面值进行赋值,所以复杂的 function&lt;- 语法糖将不起作用。当您使用 names(x) &lt;- &quot;a&quot; 时,x 值是一个可以更新的变量。该调用被翻译为类似以下内容:

x &lt;- `names&lt;-`(x, &quot;a&quot;)

这意味着 object(&quot;foo&quot;) &lt;- 1 将变成

&quot;foo&quot; &lt;- `object&lt;-`(&quot;foo&quot;, 1)

这是没有意义的。

英文:

You can't use a function like this if the first value is not "assignable". Here you have the literal string value "foo" and you cannot assign a value to that literal value so the fancy function&lt;- syntactic sugar will not work. When you use names(x) &lt;- &quot;a&quot; the x value is a variable that can be updated. The call is translated to something like

x &lt;- `names&lt;-`(x, &quot;a&quot;)

This means object(&quot;foo&quot;) &lt;- 1 would become

&quot;foo&quot; &lt;- `object&lt;-`(&quot;foo&quot;, 1)

which doesn't make sense

huangapple
  • 本文由 发表于 2023年7月17日 22:32:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76705513.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定