- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用 match.fun
时遇到问题连同test_that
当match.fun
在嵌套函数中使用。为了说明这一点,我构建了一个包含两个函数的快速玩具示例 R 包。后者简单地调用前者:
i_dont_throw_error <- function(function_name)
match.fun(function_name)("hello")
i_throw_error <- function(function_name)
i_dont_throw_error(function_name)
testthat
测试如下:
test_that("Testing for an error with match.fun one level deep.",{
print_function <- function(x)
print(x)
expect_equal(i_dont_throw_error("print_function"), "hello")
})
test_that("Testing for an error with match.fun two levels deep.",{
print_function <- function(x)
print(x)
expect_equal(i_throw_error("print_function"), "hello")
})
testthat
的输出是
==> devtools::test()
Loading testthatTest
Loading required package: testthat
Testing testthatTest
[1] "hello"
.1
1. Error: Testing for an error with match.fun two levels deep. -----------------
object 'print_function' of mode 'function' was not found
1: withCallingHandlers(eval(code, new_test_environment), error = capture_calls, message = function(c) invokeRestart("muffleMessage"))
2: eval(code, new_test_environment)
3: eval(expr, envir, enclos)
4: expect_equal(i_throw_error("print_function"), "hello") at test_test_me.R:12
5: expect_that(object, equals(expected, label = expected.label, ...), info = info, label = label)
6: condition(object)
7: compare(actual, expected, ...)
8: i_throw_error("print_function")
9: i_dont_throw_error(function_name) at C:\Users\jowhitne\Desktop\eraseMe\testthatTest/R/test_func.R:4
10: match.fun(function_name) at C:\Users\jowhitne\Desktop\eraseMe\testthatTest/R/test_func.R:1
11: get(as.character(FUN), mode = "function", envir = envir)
> print_function <- function(x)
+ print(x)
> i_throw_error("print_function")
[1] "hello"
match.fun
之后它会起作用。搜索两个环境。知道我在这里缺少什么吗?在此先感谢您的帮助。
最佳答案
相关问题:
devtools::test()
运行时计算表达式但不是在交互式运行时。
dynGet()
找到对象,因为这使用黑魔法来查找对象(也就是说我不明白它是如何工作的)。
get()
,
parent.frame()
,
parent.env()
等。参见
Hadley's Advanced R 中的环境介绍。 .
devtools::test()
确实将警告打印到控制台,所以我用它作为我提取调试信息的方式。这样做需要我编写一个有点复杂的函数来帮助解决这个问题:
print_envir = function(x, prefix = "", recursive = F, list_objects = T, max_objects = 10, use_names = T, no_attr = T, skip_beyond_global = T) {
# browser()
#use names
if (use_names) {
env_name_attr = attr(x, "name")
if (is.null(env_name_attr)) {
env_name_attr = ""
} else {
env_name_attr = sprintf(" (%s)", env_name_attr)
}
} else {
env_name_attr = ""
}
#strip attributes?
if (no_attr) {
attributes(x) = NULL
}
#get name
env_name = {capture.output(print(x))}
#get parent env name
# parent_env_name = {capture.output(print(parent.env(x)))}
#objects
if (list_objects) {
env_objects = names(x)
#limit
env_objects = na.omit(env_objects[1:max_objects])
#explicit none
if (length(env_objects) == 0) {
env_objects = "(none)"
}
} else {
env_objects = "(not requested)"
}
#issue print as warning so they come thru testthat console
warning(sprintf("%senvironment `%s`%s with objects: %s",
prefix,
env_name,
env_name_attr,
str_c(env_objects, collapse = ", ")
), call. = F)
#recursive?
if (recursive) {
#stop when parent is empty envir
if (!identical(parent.env(x), emptyenv())) {
#skip on top of global?
if (!identical(x, globalenv())) {
print_envir(parent.env(x), recursive = T, list_objects = list_objects, max_objects = max_objects, use_names = use_names, prefix = prefix, no_attr = no_attr)
}
}
}
invisible(NULL)
}
print()
的原因是这没有显示在
中的正确位置测试记录但警告。
inner_func1 = function(function_name) {
#print envirs
print_envir(environment(), "current ", recursive = T)
print_envir(parent.frame(), "parent.frame ", recursive = T)
match.fun(function_name)("hello")
}
outer_func1 = function(function_name) {
#print envirs
print_envir(environment(), "current ", recursive = T)
print_envir(parent.frame(), "parent.frame ", recursive = T)
print_envir(environment(inner_func1), "defining/enclosing ", recursive = T)
#failing call
inner_func1(function_name)
}
outer_v1
的控制台输出如下所示:
test_functions.R:13: warning: outer_v1
current environment `<environment: 0x397a2a8>` with objects: function_name
test_functions.R:13: warning: outer_v1
current environment `<environment: namespace:test.package>` with objects: print_envir, .__DEVTOOLS__, inner_func1, .packageName, inner_func2, inner_func3, outer_func1, outer_func2, outer_func3, .__NAMESPACE__.
test_functions.R:13: warning: outer_v1
current environment `<environment: 0x23aa1a0>` with objects: library.dynam.unload, system.file
test_functions.R:13: warning: outer_v1
current environment `<environment: namespace:base>` with objects: Sys.Date, c.warnings, as.expression.default, as.POSIXlt.factor, [.hexmode, unique.warnings, dimnames<-, regexpr, !, parse
test_functions.R:13: warning: outer_v1
current environment `<environment: R_GlobalEnv>` with objects: .Random.seed
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: 0x313b150>` with objects: (none)
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: 0x3d25070>` with objects: print_function
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: 0x3cff218>` with objects: (none)
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: 0x370c908>` with objects: (none)
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: namespace:test.package>` with objects: print_envir, .__DEVTOOLS__, inner_func1, .packageName, inner_func2, inner_func3, outer_func1, outer_func2, outer_func3, .__NAMESPACE__.
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: 0x23aa1a0>` with objects: library.dynam.unload, system.file
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: namespace:base>` with objects: Sys.Date, c.warnings, as.expression.default, as.POSIXlt.factor, [.hexmode, unique.warnings, dimnames<-, regexpr, !, parse
test_functions.R:13: warning: outer_v1
parent.frame environment `<environment: R_GlobalEnv>` with objects: .Random.seed
test_functions.R:13: warning: outer_v1
defining/enclosing environment `<environment: namespace:test.package>` with objects: print_envir, .__DEVTOOLS__, inner_func1, .packageName, inner_func2, inner_func3, outer_func1, outer_func2, outer_func3, .__NAMESPACE__.
test_functions.R:13: warning: outer_v1
defining/enclosing environment `<environment: 0x23aa1a0>` with objects: library.dynam.unload, system.file
test_functions.R:13: warning: outer_v1
defining/enclosing environment `<environment: namespace:base>` with objects: Sys.Date, c.warnings, as.expression.default, as.POSIXlt.factor, [.hexmode, unique.warnings, dimnames<-, regexpr, !, parse
test_functions.R:13: warning: outer_v1
defining/enclosing environment `<environment: R_GlobalEnv>` with objects: .Random.seed
(skipped because these are from inner_v1)
test_functions.R:13: error: outer_v1
object 'print_function' of mode 'function' was not found
1: expect_equal(outer_func1("print_function"), "hello") at /4tb/GP/code/test.package/tests/testthat/test_functions.R:13
2: quasi_label(enquo(object), label)
3: eval_bare(get_expr(quo), get_env(quo))
4: outer_func1("print_function")
5: inner_func1(function_name) at /code/test.package/R/functions.R:62
6: match.fun(function_name) at /code/test.package/R/functions.R:7
7: get(as.character(FUN), mode = "function", envir = envir)
current environment
是当前(在函数调用内部)环境。
0x397a2a8
(功能环境)> namespace:test.package
> 0x23aa1a0
> namespace:base
> R_GlobalEnv
.这些都没有我们想要的对象,即 print_function
. 0x3d25070
(一个空的环境,不知道为什么会在那里)> 0x3d25070
(有我们的目标!)> 0x3cff218
(另一个空环境)> 0x370c908
(又一)> namespace:test.package
> 0x23aa1a0
> namespace:base
> R_GlobalEnv
. namespace:test.package
> 0x23aa1a0
> namespace:base
> R_GlobalEnv
. get(function_name, envir = parent.frame(n = 2))
获取函数。 .因此,第二次迭代是:
inner_func2 = function(function_name) {
#print envirs
print_envir(environment(), "current ", recursive = T)
print_envir(parent.frame(), "parent.frame ", recursive = T)
#try to get object in current envir
#if it isnt there, try parent.frame
if (exists(function_name)) {
warning(sprintf("%s exists", function_name))
func = get(function_name)
} else {
warning(sprintf("%s does not exist", function_name))
func = get(function_name, envir = parent.frame(n = 2))
}
func("hello")
}
outer_func2 = function(function_name) {
#print envirs
print_envir(environment(), "current ", recursive = T)
print_envir(parent.frame(), "parent.frame ", recursive = T)
print_envir(environment(inner_func2), "defining/enclosing ", recursive = T)
inner_func2(function_name)
}
parent.frame(n = 2)
道路。
devtools::test()
进行测试我们发现
outer_v2
现在可以用了,但我们坏了
inner_v2
虽然它以交互方式工作。如果我们检查日志,我们会看到:
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: 0x41f0d78>` with objects: (none)
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: 0x478aa60>` with objects: print_function
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: 0x47546d0>` with objects: (none)
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: 0x4152c20>` with objects: (none)
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: namespace:test.package>` with objects: print_envir, .__DEVTOOLS__, inner_func1, .packageName, inner_func2, inner_func3, outer_func1, outer_func2, outer_func3, .__NAMESPACE__.
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: 0x2df41a0>` with objects: library.dynam.unload, system.file
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: namespace:base>` with objects: Sys.Date, c.warnings, as.expression.default, as.POSIXlt.factor, [.hexmode, unique.warnings, dimnames<-, regexpr, !, parse
test_functions.R:20: warning: inner_v2
parent.frame environment `<environment: R_GlobalEnv>` with objects: .Random.seed
test_functions.R:20: warning: inner_v2
print_function does not exist
test_functions.R:20: error: inner_v2
object 'print_function' not found
1: expect_equal(inner_func2("print_function"), "hello") at /code/test.package/tests/testthat/test_functions.R:20
2: quasi_label(enquo(object), label)
3: eval_bare(get_expr(quo), get_env(quo))
4: inner_func2("print_function")
5: get(function_name, envir = parent.frame(n = 2)) at /code/test.package/R/functions.R:23
parent.frame(n = 2)
来自与以前不同的地方,这改变了一些东西。如果我们将其替换为
parent.frame(n = 1)
它再次起作用。
parent.frame()
不是一个彻底的解决方案,因为人们需要知道要返回多少步骤,这取决于一个人有多少嵌套函数。有没有更好的办法?是的。
dynGet()
使用黑魔法自己解决这个问题(即我不知道它是如何工作的)。人们大概也可以通过实现自定义
get2()
来实现这一点。循环遍历
n
的所有可能值在
parent.frame()
(留给读者练习)。
inner_func3 = function(function_name) {
#print envirs
print_envir(environment(), "current ", recursive = T)
print_envir(parent.frame(), "parent.frame ", recursive = T)
#try to get object in current envir
#if it isnt there, try parent.frame
if (exists(function_name)) {
warning(sprintf("%s exists", function_name))
func = get(function_name)
} else {
warning(sprintf("%s does not exist", function_name))
func = dynGet(function_name)
}
func("hello")
}
outer_func3 = function(function_name) {
#print envirs
print_envir(environment(), "current ", recursive = T)
print_envir(parent.frame(), "parent.frame ", recursive = T)
print_envir(environment(inner_func3), "defining/enclosing ", recursive = T)
inner_func3(function_name)
}
devtools::test()
测试。万岁!
关于r - test_that 与 match.fun 一起使用时,在两级深度时抛出意外错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34345945/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许在 Stack Overflow 上提出有关通用计算硬件和软件的问题。您可以编辑问题,使其成为
当我尝试在 db2 中创建表时,它抛出以下错误 $ db2 CREATE TABLE employee(emp_id INT NOT NULL, emp_name VARCHAR(100)) sh:
我有: while (i < l) { if (one === two) { continue; } i++; } 但是 JSLint 说: Problem at line 1 chara
所以我有这个代码: char inputs[10] = ""; int numInputs = 0; while (numInputs < 10){ char c; printf("E
var ninja = { name: 'Ninja', say: function () { return 'I am a ' + this.name; }
我收到一个我不明白的错误,请注意,我是编码新手,所以这可能是一个简单的错误。 #include using namespace std; int main() { //Initialise Fahr
我正在使用 javascript 和 react,由于某种原因,我收到了一个奇怪的 token 错误。 这是发生错误的代码: renderNavBar() { if (!this.us
Closed. This question is off-topic。它当前不接受答案。
由于某种我无法解释的原因,编译器正在输出一个错误,指出它发现了一个意外的#else 标记。 这发生在文件的开头: #if defined( _USING_MFC ) #include "stda
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
这个问题在这里已经有了答案: Difference between sh and Bash (11 个答案) 关闭 2 年前。 我正在编写一个简单的 bash 脚本,我在 XX `(' unexpe
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 此问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-topic
我在 Windows 7 上编写了一个脚本,它不断给我一个错误“(此时出乎意料。”对于以下代码 if %vardns%=="NODNS" ( netsh interface ipv4 set ad
我正在尝试使用xmlstarlet(使用xpath)解析XML文件,但是出现语法错误,并且我不知道如何更正我的代码。 这是我的脚本: #!/bin/bash if [ $1=="author" ];
以下脚本旨在在目录中的所有文件上运行程序“senna”,并将每个文件的输出(保留输入文件名)写入另一个目录 for file in ./Data/in/*; do ./senna -iobta
我从 challengers.coffee 运行此代码,并收到错误 ActionView::Template::Error (SyntaxError: [stdin]:3:31:unexpected
我在 config.db.database; 行中有语法错误(意外的标记“.”)。这是我在文件中的代码 const config = require('../config/config') const
这一定很明显,但是我无法使它正常工作。我正在尝试传输应该用于构建$ classKey的对象,这反过来又导致删除所需的软件(amd64或i386)。好吧,这里的代码: $name = @("softwa
我正在使用 1.3.7 版学习 Grails,但我一直无缘无故地遇到以下语法错误: unexpected token: mapping @ line x, column y. 有一次,我通过运行“gr
我正在尝试找出这段Pascal代码的问题 function Factorial(n: integer): integer; begin if n = 0 then Result := 1
我是一名优秀的程序员,十分优秀!