rtrycatch块中的变量作用域:是否

时间:2022-05-06 20:23:39

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")