Consider the following code:
考虑下面的代码:
test1 <- "a"
test2 <- "a"
tryCatch(stop(), error= function(err){
print(test1)
print(test2)
test1 <- "b"
test2 <<- "b"
})
Result:
结果:
print(test1)
[1] "a"
print(test2)
[1] "b"
The value of variable test1 is visible within the tryCatch block, but changing it with "<-" operator does not affect its value outside the tryCatch block.
变量test1的值在tryCatch块中是可见的,但是使用“<-”操作符更改它不会影响它在tryCatch块之外的值。
If a new value is assigned with <<- it has the desired effect. Why?
如果一个新值被赋值为<<-它具有期望的效果。为什么?
Is using the <<- operator within the tryCatch block a recommended way to change the value of a local variable outside this block? Could there be some unexpected sideffects?
在tryCatch块中使用<<- operator是更改块外局部变量值的推荐方法吗?会有一些意想不到的副作用吗?
EDIT: Based on a Bernhard answer, does the following code make up for the right approach to this problem?
编辑:基于Bernhard的答案,下面的代码是否弥补了这个问题的正确方法?
test1 <- "a"
test2 <- "a"
new_values<-tryCatch(
{
print("hello")
stop()
}
, error= function(err){
# I want to change the test1 and test 2 variables to "b" only if error occurred.
test1 <- "b"
test2 <- "b"
return(list(test1=test1,test2=test2))
})
if (is.list(new_values))
{
test1<-new_values$test1
test2<-new_values$test2
}
Result:
结果:
> print(test1)
[1] "b"
> print(test2)
[1] "b"
1 个解决方案
#1
3
The '<<-' is made for side effects that do not belong to R. Use it never, or only if memory or speed force you to do so. A block has it's own scope and if you want to give data from within a block to the 'outside' environement, that there is return() for that task:
“<- -”是针对不属于r的副作用而设计的,永远不要使用它,或者只有在内存或速度迫使您这样做时才使用它。一个块有它自己的作用域,如果你想从一个块中向“外部”环境提供数据,那么这个任务有return():
test2 <- "a"
test2 <- tryCatch(stop(), error= function(err){
somevariable <- "b"
return(somevariable)
})
This makes it clear to everyone, that toplevel test2 is set to "a" and then, that toplevel test2 is set to something else. With '<<-' it happens easily, that some function changes toplevel test2 and someone wonders, why toplevel test2 has been changed at all. Just don't <<-.
这使每个人都清楚地认识到,toplevel test2被设置为“a”,然后,toplevel test2被设置为其他东西。使用“<-”很容易发生这种情况,一些函数改变了toplevel test2,有人想知道为什么toplevel test2已经被改变了。只是不要< < -。
If there is a need to return more than one result, return a list or an object of the results.
如果需要返回多个结果,则返回结果的列表或对象。
EDIT: The OP has pointed out that you need to be carefull with the return statements, as they do not only end the current block, but also the current function. A possible solution is, to run the computations in functions instead of simple blocks. The following example should illustrate this:
编辑:OP指出您需要注意返回语句,因为它们不仅结束当前块,而且还结束当前函数。一个可能的解决方案是,在函数中运行计算而不是简单的块。下面的例子应该说明这一点:
safediv <- function(a, b){
normalDo <- function(a, b){
return(list(value=a/b, message=NULL))
}
exceptionalDo <- function(err){
return(list(value=NaN, message="caught an error! Change global variable?"))
}
results <- tryCatch(normalDo(a, b), error=exceptionalDo)
print("safediv is still running after the returns within the functions.")
return(results)
}
# try it out
safediv(5, 3)
safediv(5, 0)
safediv(5, "a")
#1
3
The '<<-' is made for side effects that do not belong to R. Use it never, or only if memory or speed force you to do so. A block has it's own scope and if you want to give data from within a block to the 'outside' environement, that there is return() for that task:
“<- -”是针对不属于r的副作用而设计的,永远不要使用它,或者只有在内存或速度迫使您这样做时才使用它。一个块有它自己的作用域,如果你想从一个块中向“外部”环境提供数据,那么这个任务有return():
test2 <- "a"
test2 <- tryCatch(stop(), error= function(err){
somevariable <- "b"
return(somevariable)
})
This makes it clear to everyone, that toplevel test2 is set to "a" and then, that toplevel test2 is set to something else. With '<<-' it happens easily, that some function changes toplevel test2 and someone wonders, why toplevel test2 has been changed at all. Just don't <<-.
这使每个人都清楚地认识到,toplevel test2被设置为“a”,然后,toplevel test2被设置为其他东西。使用“<-”很容易发生这种情况,一些函数改变了toplevel test2,有人想知道为什么toplevel test2已经被改变了。只是不要< < -。
If there is a need to return more than one result, return a list or an object of the results.
如果需要返回多个结果,则返回结果的列表或对象。
EDIT: The OP has pointed out that you need to be carefull with the return statements, as they do not only end the current block, but also the current function. A possible solution is, to run the computations in functions instead of simple blocks. The following example should illustrate this:
编辑:OP指出您需要注意返回语句,因为它们不仅结束当前块,而且还结束当前函数。一个可能的解决方案是,在函数中运行计算而不是简单的块。下面的例子应该说明这一点:
safediv <- function(a, b){
normalDo <- function(a, b){
return(list(value=a/b, message=NULL))
}
exceptionalDo <- function(err){
return(list(value=NaN, message="caught an error! Change global variable?"))
}
results <- tryCatch(normalDo(a, b), error=exceptionalDo)
print("safediv is still running after the returns within the functions.")
return(results)
}
# try it out
safediv(5, 3)
safediv(5, 0)
safediv(5, "a")