In PHP we can do error_reporting(E_ALL)
or error_reporting(E_ALL|E_STRICT)
to have warnings about suspicious code. In g++ you can supply -Wall
(and other flags) to get more checking of your code. Is there some similar in R?
在PHP中,我们可以执行error_reporting(E_ALL)或error_reporting(E_ALL | E_STRICT)来发出有关可疑代码的警告。在g ++中,您可以提供-Wall(和其他标志)来更多地检查代码。 R中有类似的吗?
As a specific example, I was refactoring a block of code into some functions. In one of those functions I had this line:
作为一个具体的例子,我在一些函数中重构了一段代码。在其中一个函数中,我有这一行:
if(nm %in% fields$non_numeric)...
Much later I realized that I had overlooked adding fields
to the parameter list, but R did not complain about an undefined variable.
很久以后我意识到我忽略了在参数列表中添加字段,但是R没有抱怨未定义的变量。
3 个解决方案
#1
6
(Posting as an answer rather than a comment)
(作为答案而不是评论发布)
How about ?codetools::checkUsage
(codetools
is a built-in package) ... ?
怎么样?codetools :: checkUsage(codetools是一个内置包)......?
#2
3
This is not really an answer, I just can't resist showing how you could declare globals explicitly. @Ben Bolker should post his comment as the Answer.
这不是一个真正的答案,我无法抗拒显示你如何明确地声明全局变量。 @Ben Bolker应该将他的评论作为答案发表。
To avoiding seeing globals, you can take a function "up" one environment -- it'll be able to see all the standard functions and such (mean
, etc), but not anything you put in the global environment:
为了避免看到全局变量,你可以在一个环境中“运行”一个函数 - 它将能够看到所有标准函数等(意思是等),但不是你在全局环境中放置的任何东西:
explicit.globals = function(f) {
name = deparse(substitute(f))
env = parent.frame()
enclos = parent.env(.GlobalEnv)
environment(f) = enclos
env[[name]] = f
}
Then getting a global is just retrieving it from .GlobalEnv
:
然后获取全局只是从.GlobalEnv中检索它:
global = function(n) {
name = deparse(substitute(n))
env = parent.frame()
env[[name]] = get(name, .GlobalEnv)
}
assign('global', global, env=baseenv())
And it would be used like
它会被用作
a = 2
b = 3
f = function() {
global(a)
a
b
}
explicit.globals(f)
And called like
并称之为
> f()
Error in f() : object 'b' not found
I personally wouldn't go for this but if you're used to PHP it might make sense.
我个人不会这样做,但如果你习惯了PHP,它可能是有道理的。
#3
1
Summing up, there is really no correct answer: as Owen and gsk3 point out, R functions will use globals if a variable is not in the local scope. This may be desirable in some situations, so how could the "error" be pointed out?
总而言之,确实没有正确的答案:正如Owen和gsk3所指出的,如果变量不在本地范围内,R函数将使用全局变量。在某些情况下这可能是理想的,那么如何指出“错误”呢?
checkUsage() does nothing that R's built-in error-checking does not (in this case). checkUsageEnv(.GlobalEnv) is a useful way to check a file of helper functions (and might be great as a pre-hook for svn or git; or as part of an automated build process).
checkUsage()没有做任何R的内置错误检查(在这种情况下)。 checkUsageEnv(.GlobalEnv)是一种检查辅助函数文件的有用方法(可能非常适合作为svn或git的预挂钩;或者作为自动构建过程的一部分)。
I feel the best solution when refactoring is: at the very start to move all global code to a function (e.g. call it main()
) and then the only global code would be to call that function. Do this first, then start extracting functions, etc.
我认为重构的最佳解决方案是:在一开始将所有全局代码移动到一个函数(例如,将其称为main()),然后唯一的全局代码就是调用该函数。首先执行此操作,然后开始提取功能等。
#1
6
(Posting as an answer rather than a comment)
(作为答案而不是评论发布)
How about ?codetools::checkUsage
(codetools
is a built-in package) ... ?
怎么样?codetools :: checkUsage(codetools是一个内置包)......?
#2
3
This is not really an answer, I just can't resist showing how you could declare globals explicitly. @Ben Bolker should post his comment as the Answer.
这不是一个真正的答案,我无法抗拒显示你如何明确地声明全局变量。 @Ben Bolker应该将他的评论作为答案发表。
To avoiding seeing globals, you can take a function "up" one environment -- it'll be able to see all the standard functions and such (mean
, etc), but not anything you put in the global environment:
为了避免看到全局变量,你可以在一个环境中“运行”一个函数 - 它将能够看到所有标准函数等(意思是等),但不是你在全局环境中放置的任何东西:
explicit.globals = function(f) {
name = deparse(substitute(f))
env = parent.frame()
enclos = parent.env(.GlobalEnv)
environment(f) = enclos
env[[name]] = f
}
Then getting a global is just retrieving it from .GlobalEnv
:
然后获取全局只是从.GlobalEnv中检索它:
global = function(n) {
name = deparse(substitute(n))
env = parent.frame()
env[[name]] = get(name, .GlobalEnv)
}
assign('global', global, env=baseenv())
And it would be used like
它会被用作
a = 2
b = 3
f = function() {
global(a)
a
b
}
explicit.globals(f)
And called like
并称之为
> f()
Error in f() : object 'b' not found
I personally wouldn't go for this but if you're used to PHP it might make sense.
我个人不会这样做,但如果你习惯了PHP,它可能是有道理的。
#3
1
Summing up, there is really no correct answer: as Owen and gsk3 point out, R functions will use globals if a variable is not in the local scope. This may be desirable in some situations, so how could the "error" be pointed out?
总而言之,确实没有正确的答案:正如Owen和gsk3所指出的,如果变量不在本地范围内,R函数将使用全局变量。在某些情况下这可能是理想的,那么如何指出“错误”呢?
checkUsage() does nothing that R's built-in error-checking does not (in this case). checkUsageEnv(.GlobalEnv) is a useful way to check a file of helper functions (and might be great as a pre-hook for svn or git; or as part of an automated build process).
checkUsage()没有做任何R的内置错误检查(在这种情况下)。 checkUsageEnv(.GlobalEnv)是一种检查辅助函数文件的有用方法(可能非常适合作为svn或git的预挂钩;或者作为自动构建过程的一部分)。
I feel the best solution when refactoring is: at the very start to move all global code to a function (e.g. call it main()
) and then the only global code would be to call that function. Do this first, then start extracting functions, etc.
我认为重构的最佳解决方案是:在一开始将所有全局代码移动到一个函数(例如,将其称为main()),然后唯一的全局代码就是调用该函数。首先执行此操作,然后开始提取功能等。