{"action":"opened","issue":{"url":"https://api.github.com/repos/jimhester/withr/issues/32","labels_url":"https://api.github.com/repos/jimhester/withr/issues/32/labels{/name}","comments_url":"https://api.github.com/repos/jimhester/withr/issues/32/comments","events_url":"https://api.github.com/repos/jimhester/withr/issues/32/events","html_url":"https://github.com/jimhester/withr/issues/32","id":114885620,"number":32,"title":"with_tempfile","user":{"login":"jimhester","id":205275,"avatar_url":"https://avatars.githubusercontent.com/u/205275?v=3","gravatar_id":"","url":"https://api.github.com/users/jimhester","html_url":"https://github.com/jimhester","followers_url":"https://api.github.com/users/jimhester/followers","following_url":"https://api.github.com/users/jimhester/following{/other_user}","gists_url":"https://api.github.com/users/jimhester/gists{/gist_id}","starred_url":"https://api.github.com/users/jimhester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jimhester/subscriptions","organizations_url":"https://api.github.com/users/jimhester/orgs","repos_url":"https://api.github.com/users/jimhester/repos","events_url":"https://api.github.com/users/jimhester/events{/privacy}","received_events_url":"https://api.github.com/users/jimhester/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-11-03T18:59:24Z","updated_at":"2015-11-03T18:59:24Z","closed_at":null,"body":"This takes an idea from `bquote()` and allows you to specify what variable to assign the temporary filename to in your code by surrounding it in a `.()` call. Then these files are cleaned up afterwards. The function definition and example usage is below. An alternative interface would be to have a separate argument to specify variable names to use, but I think it is a little nicer to specify them inline. Any thoughts @krlmlr?\r\n\r\n``` r\r\nwith_tempfile <- function(code, envir = parent.frame()) {\r\n  # Adapted from bquote\r\n  vars <- character()\r\n  unquote <- function(e) {\r\n    if (is.pairlist(e))\r\n      as.pairlist(lapply(e, unquote))\r\n    else if (length(e) <= 1) e\r\n    else if (e[[1]] == as.name(\".\")) {\r\n      vars <<- append(vars, as.character(e[[2]]))\r\n      e[[2]]\r\n    }\r\n    else as.call(lapply(e, unquote))\r\n  }\r\n  code <- unquote(substitute(code))\r\n  if (length(vars) == 0) {\r\n    stop(\"Must specify a variable to store the temp filename using .() in your\r\n         code\", call. = FALSE)\r\n  }\r\n\r\n  env <- new.env(parent = envir)\r\n  for (var in vars) {\r\n    assign(var, tempfile(), envir = env)\r\n  }\r\n  on.exit(unlink(mget(vars, envir = env)))\r\n\r\n  eval(code, envir = env)\r\n}\r\n\r\nfiles <- character()\r\n\r\nwith_tempfile({\r\n  writeLines(\"hi\", con = .(tmp))\r\n  writeLines(\"ho\", con = .(tmp2))\r\n  print(readLines(tmp))\r\n  print(readLines(tmp2))\r\n  files <<- append(files, tmp)\r\n  files <<- append(files, tmp2)\r\n})\r\n#> [1] \"hi\"\r\n#> [1] \"ho\"\r\n\r\nreadLines(files[1])\r\n#> Warning in file(con, \"r\"): cannot open file '/tmp/RtmpjcsoCQ/\r\n#> filecc56011eda5': No such file or directory\r\n#> Error in file(con, \"r\"): cannot open the connection\r\nreadLines(files[2])\r\n#> Warning in file(con, \"r\"): cannot open file '/tmp/RtmpjcsoCQ/\r\n#> filecc52fad8b97': No such file or directory\r\n#> Error in file(con, \"r\"): cannot open the connection\r\n```"}}