4

Here is my code. It produces infinite loop, because value of something variable does not change within captured error. Is it supposed to be this way? How can I fix it so that value of something changes to FALSE?

something <- TRUE
counter <- 1
while(something){
  print(counter)  
  tryTest = tryCatch(
    {
      arima(rep(1,3), order = c(1,0,0))
    }, 
    warning = function(w) {

      print('this is warning')
      print(w)
    },
    error = function(e) {
      something <- FALSE
      print('this is error')
      print(e)
    },
    finally = {}
  )
  counter <- (counter +1)
}
user1700890
  • 6,206
  • 15
  • 77
  • 160
  • 2
    Define your warning function as: `warning = function(w) { something < – nadizan Jan 22 '18 at 22:18
  • 1
    @nadizan, I just tried it and it does not work, still infinite loop – user1700890 Jan 22 '18 at 22:32
  • @nadizan the problem with your suggestion is that the parent scope of the lambda is still inside the tryCatch function and is not the outer scope. – Mosquite Jan 22 '18 at 22:55
  • As a side note. On error, the return value of the error function is returned by `tryCatch` on error. you could always use that to stop your loop. Condition on `tryTest` being non NULL to continue your loop. Just make sure to return something non null on a warning. – Mosquite Jan 22 '18 at 22:59
  • @user1700890, this works completely fine for me. `something – nadizan Jan 23 '18 at 10:36
  • @nadizan you are right. Thank you! Funny how I wrote about catching error, but you put code into warning block. This arima generates both error and warning, and if you add `something < – user1700890 Jan 23 '18 at 15:18
  • 1
    See also: https://stackoverflow.com/questions/38482937/variable-scope-in-r-trycatch-block-is-necessary-to-change-local-variable-de – climatestudent Aug 16 '21 at 12:00

1 Answers1

5

This happens because the environment of something in the outer code is different from the environment of something in your lambda:

function(e) {
    something <- FALSE
    print('this is error')
    print(e)
}

So setting something <- FALSE in your lambda actually sets a different something then in the outer code. To fix this you can either 1) make something a global variable or 2) create an environment to use something in.

1)

assign("something", TRUE, env=globalenv())

to set the variable and

get("something", env=globalenv())

to access the variable.

You can also set something inside your lambda in the same way:

assign("something", FALSE, env=globalenv())

or

2)

First create a new variable:

env=new.env()

Then set and access your variable in a similar way as before:

assign("something", TRUE, env=env)
get("something", env=env)

You can assign something inside your lambda with:

assign("something", FALSE, env=env)

Using env is possible because R copies variables to child environments. However if you set a variable in a child environment (like when you did `somethi

Mosquite
  • 519
  • 1
  • 6
  • 15