R CMD 检查注意:`没有全局变量的可见绑定`,在 S3 泛型中定义变量并在方法中使用它时
R CMD check NOTE: `No visible binding for global variable`, when defining a variable in an S3 generic and using it in a method
考虑以下代码:
greet <- function(object) {
greeting <- "hola"
UseMethod("greet", object)
}
greet.character <- function(object)
paste(greeting, object)
greet("Whosebug")
#> [1] "hola Whosebug"
由 reprex package (v0.3.0)
于 2021-02-03 创建
显然,greet.character
方法的执行环境填充了泛型中创建的变量,在 UseMethod()
之前,因此代码按预期工作。
但是,在包中包含这些定义将导致在 R CMD 检查时出现以下注释:
> checking R code for possible problems ... NOTE
greet.character: no visible binding for global variable ‘greeting’
Undefined global functions or variables:
greeting
您可以在 this repository 找到说明该问题的示例包。
现在,我知道我可以用globalVariables()
关闭NOTE,但我仍然对NOTE最初的来源感到困惑。所以我的问题是:
上面的例子在 R 包中被认为是“不好的做法”有什么内在原因吗?在现实生活中的例子中,我使用这样的构造来避免在多个方法中重复代码。
如果没有,有没有比使用globalVariables()
更好的选择?
回答我自己,我认为这种做法会导致令人困惑的行为,因为 UseMethod()
使用相同的参数生成适当方法的调用;暗示对是泛型参数的变量的修改(不像上面示例中的greeting
)不会传播到方法。
现在我正在定义要在每个方法开始时调用的额外函数,以执行我最初在泛型中执行的复杂计算。如果这些函数需要很多参数,这也会导致代码繁琐,但这是我目前找到的最佳解决方案。
我会把这个开放一段时间,看看是否有人可以提出其他方法。
考虑以下代码:
greet <- function(object) {
greeting <- "hola"
UseMethod("greet", object)
}
greet.character <- function(object)
paste(greeting, object)
greet("Whosebug")
#> [1] "hola Whosebug"
由 reprex package (v0.3.0)
于 2021-02-03 创建显然,greet.character
方法的执行环境填充了泛型中创建的变量,在 UseMethod()
之前,因此代码按预期工作。
但是,在包中包含这些定义将导致在 R CMD 检查时出现以下注释:
> checking R code for possible problems ... NOTE
greet.character: no visible binding for global variable ‘greeting’
Undefined global functions or variables:
greeting
您可以在 this repository 找到说明该问题的示例包。
现在,我知道我可以用globalVariables()
关闭NOTE,但我仍然对NOTE最初的来源感到困惑。所以我的问题是:
上面的例子在 R 包中被认为是“不好的做法”有什么内在原因吗?在现实生活中的例子中,我使用这样的构造来避免在多个方法中重复代码。
如果没有,有没有比使用
globalVariables()
更好的选择?
回答我自己,我认为这种做法会导致令人困惑的行为,因为 UseMethod()
使用相同的参数生成适当方法的调用;暗示对是泛型参数的变量的修改(不像上面示例中的greeting
)不会传播到方法。
现在我正在定义要在每个方法开始时调用的额外函数,以执行我最初在泛型中执行的复杂计算。如果这些函数需要很多参数,这也会导致代码繁琐,但这是我目前找到的最佳解决方案。
我会把这个开放一段时间,看看是否有人可以提出其他方法。