r - 如何更改 $ 运算符在环境中的行为?
问题描述
我想覆盖美元运算符的行为,这样如果我有
x <- new.env()
x$foo <- 3
例如会打电话给某事。我试图寻找可能的功能,例如$
,但我对内部的了解还不够好。
我试过这个:
`$` <- function(a, b) {
res <- .Primitive("$")(a, b);
print(res);
if(is.null(res)) { print("null!") };
return(res)
}
它似乎工作,但是:
> x$foobar
NULL
[1] "null!"
NULL
> x$foobar <- 3
> x$foobar
NULL
[1] "null!"
NULL
>
因此,尽管被覆盖,它似乎仍然为空。
解决方案
R s 的正常行为environment
:
myenv <- new.env(parent = emptyenv())
myenv$foo <- 3
class(myenv)
# [1] "environment"
myenv$foo
# [1] 3
myenv$foobar
# NULL
让我们定义一个超类(我会命名它environment2
,在这里随意发挥创意)并覆盖$
该类:
class(myenv) <- c("environment2", "environment")
`$.environment2` <- function(x, name) {
stopifnot(name %in% names(x))
NextMethod()
}
myenv$foo
# [1] 3
myenv$foobar
# Error in `$.environment2`(myenv, foobar) : name %in% names(x) is not TRUE
如果您愿意,可以使用带有 的if
语句stop
或(在 R-4 或更新版本中)将条件命名为stopifnot
.
`$.environment2` <- function(x, name) {
if (!name %in% names(x)) stop("something meaningful", call. = FALSE)
NextMethod()
}
`$.environment2` <- function(x, name) {
stopifnot(
"something meaningful" = name %in% names(x)
)
NextMethod()
}
### both render
myenv$foobar
# Error in `$.environment2`(myenv, foobar) : something meaningful
它们是相对等价的,但是使用if
/stop
可以减少错误上下文:
`$.environment2` <- function(x, name) {
if (!name %in% names(x)) stop("something meaningful", call. = FALSE)
NextMethod()
}
myenv$foobar
# Error: something meaningful
推荐阅读
- ios - 另一个链接器命令失败,退出代码为 1
- mysql - 在 slick 操作中使用 scala 集合等价物是否有害?
- android - 在Android的内部布局中设置文本字段的值
- html - 在聚合物中传递数组
- django - 在序列化程序中覆盖创建
- php - 如何模拟 Magento 2 的日期时间
- azure - 使用 Xamarin.iOS 的 Azure Active Directory 身份验证过程
- javascript - 商店补水完成后如何更新 App.js 中的状态?
- xml - Nifi SplitXML 和 EvaluateXPath 性能和内存使用情况?
- javascript - 将模块设置为 ES2017 时出现 tsconfig 错误