Dear list members,
is it possible to set some options only inside a function so that the original options are restored once the function is finished or aborted due to an error? Until now I do something like:
dummy=function()
{
old.options=options(error=dummy1())
....
options(old.options)
}
This works for most cases but when the function terminates because of an error and its last command is not run, error=dummy1() still remains as an option. Is there any way around this?
Cheers
Jannis
setting options only inside functions
15 messages · Jannis, Jeremy Hetzel, Uwe Ligges +5 more
See ?on.exit Jeremy
On Wednesday, April 27, 2011 9:16:13 AM UTC-4, Jannis wrote:
Dear list members,
is it possible to set some options only inside a function so that the
original options are restored once the function is finished or aborted due
to an error? Until now I do something like:
dummy=function()
{
old.options=options(error=dummy1())
....
options(old.options)
}
This works for most cases but when the function terminates because of an
error and its last command is not run, error=dummy1() still remains as an
option. Is there any way around this?
Cheers
Jannis
______________________________________________ R-h... at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
On 27.04.2011 15:16, Jannis wrote:
Dear list members,
is it possible to set some options only inside a function so that the original options are restored once the function is finished or aborted due to an error? Until now I do something like:
dummy=function()
{
old.options=options(error=dummy1())
....
options(old.options)
}
This works for most cases but when the function terminates because of an error and its last command is not run, error=dummy1() still remains as an option. Is there any way around this?
See ?on.exit:
dummy <- function()
{
old.options <- options(error=dummy1())
on.exit(options(old.options))
....
}
Uwe Ligges
Cheers Jannis
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
There is probably a more elegant way to do this, but you could write
it into dummy1():
dummy1 <- function()
{
...original function
options(old.options)
}
Alternatively, you could use ?tryCatch with the finally argument as a
call to options.
HTH,
Jon
On Wed, Apr 27, 2011 at 9:16 AM, Jannis <bt_jannis at yahoo.de> wrote:
Dear list members,
is it possible to set some options only inside a function so that the original options are restored once the function is finished or aborted due to an error? ?Until now I do something like:
dummy=function()
{
?old.options=options(error=dummy1())
?....
?options(old.options)
}
This works for most cases but when the function terminates because of an error and its last command is not run, error=dummy1() still remains as an option. Is there any way around this?
Cheers
Jannis
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
=============================================== Jon Daily Technician =============================================== #!/usr/bin/env outside # It's great, trust me.
Thanks to all who supplied suggestions. All of them worked. The best solution, however, was to wrap the stuff inside dummy() after the options(...) into a try() command. That way it also worked with the following setup:
dummy=function()
{
old.options=options(error=quote{dummy1()})
try(....,silent=TRUE)
options(old.options)
}
options(error=quote{dummy()})
The suggestion of Uwe did not work with these nested error handling functions. I, however, did not state my problem precisely enough for this.
Thanks again
Jannis
--- Jonathan Daily <biomathjdaily at gmail.com> schrieb am Mi, 27.4.2011:
Von: Jonathan Daily <biomathjdaily at gmail.com>
Betreff: Re: [R] setting options only inside functions
An: "Jannis" <bt_jannis at yahoo.de>
CC: r-help at r-project.org
Datum: Mittwoch, 27. April, 2011 13:35 Uhr
There is probably a more elegant way
to do this, but you could write
it into dummy1():
dummy1 <- function()
{
...original function
options(old.options)
}
Alternatively, you could use ?tryCatch with the finally
argument as a
call to options.
HTH,
Jon
On Wed, Apr 27, 2011 at 9:16 AM, Jannis <bt_jannis at yahoo.de>
wrote:
Dear list members, is it possible to set some options only inside a
function so that the original options are restored once the function is finished or aborted due to an error? ?Until now I do something like:
dummy=function()
{
?old.options=options(error=dummy1())
?....
?options(old.options)
}
This works for most cases but when the function
terminates because of an error and its last command is not run, error=dummy1() still remains as an option. Is there any way around this?
Cheers Jannis
______________________________________________ R-help at r-project.org
mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained,
reproducible code.
-- =============================================== Jon Daily Technician =============================================== #!/usr/bin/env outside # It's great, trust me.
-----Original Message-----
From: r-help-bounces at r-project.org
[mailto:r-help-bounces at r-project.org] On Behalf Of Jannis
Sent: Wednesday, April 27, 2011 11:16 AM
To: Jonathan Daily
Cc: r-help at r-project.org
Subject: Re: [R] setting options only inside functions
Thanks to all who supplied suggestions. All of them worked.
The best solution, however, was to wrap the stuff inside
dummy() after the options(...) into a try() command. That way
it also worked with the following setup:
dummy=function()
{
old.options=options(error=quote{dummy1()})
try(....,silent=TRUE)
options(old.options)
}
options(error=quote{dummy()})
This has the side effect of ignoring errors
and even hiding the error messages. If you
are concerned about multiple calls to on.exit()
in one function you could define a new function
like
withOptions <- function(optionList, expr) {
oldOpts <- options(optionList)
on.exit(options(oldOpts))
expr # lazily evaluate
}
and use it like
> withOptions(list(warn=0), { warning("Hmm"); stop("Oops")})
Error in withOptions(list(warn = 0), { : Oops
In addition: Warning message:
In withOptions(list(warn = 0), { : Hmm
> withOptions(list(warn=1), { warning("Hmm"); stop("Oops")})
Warning in withOptions(list(warn = 1), { : Hmm
Error in withOptions(list(warn = 1), { : Oops
> withOptions(list(warn=2), { warning("Hmm"); stop("Oops")})
Error in withOptions(list(warn = 2), { : (converted from warning) Hmm
> withOptions(list(warn=-1), { warning("Hmm"); stop("Oops")})
Error in withOptions(list(warn = -1), { : Oops
> getOption("warn") # it started out as 0
[1] 0
or
> withOptions(list(width=40), print(1:30))
[1] 1 2 3 4 5 6 7 8 9 10 11 12
[13] 13 14 15 16 17 18 19 20 21 22 23 24
[25] 25 26 27 28 29 30
> getOption("width")
[1] 80
Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
The suggestion of Uwe did not work with these nested error handling functions. I, however, did not state my problem precisely enough for this. Thanks again Jannis --- Jonathan Daily <biomathjdaily at gmail.com> schrieb am Mi, 27.4.2011:
Von: Jonathan Daily <biomathjdaily at gmail.com>
Betreff: Re: [R] setting options only inside functions
An: "Jannis" <bt_jannis at yahoo.de>
CC: r-help at r-project.org
Datum: Mittwoch, 27. April, 2011 13:35 Uhr
There is probably a more elegant way
to do this, but you could write
it into dummy1():
dummy1 <- function()
{
...original function
options(old.options)
}
Alternatively, you could use ?tryCatch with the finally
argument as a
call to options.
HTH,
Jon
On Wed, Apr 27, 2011 at 9:16 AM, Jannis <bt_jannis at yahoo.de>
wrote:
Dear list members, is it possible to set some options only inside a
function so that the original options are restored once the function is finished or aborted due to an error? ?Until now I do something like:
dummy=function()
{
?old.options=options(error=dummy1())
?....
?options(old.options)
}
This works for most cases but when the function
terminates because of an error and its last command is not run, error=dummy1() still remains as an option. Is there any way around this?
Cheers Jannis
______________________________________________ R-help at r-project.org
mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- =============================================== Jon Daily Technician =============================================== #!/usr/bin/env outside # It's great, trust me. ______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
This has the side effect of ignoring errors
and even hiding the error messages. ?If you
are concerned about multiple calls to on.exit()
in one function you could define a new function
like
?withOptions <- function(optionList, expr) {
? oldOpts <- options(optionList)
? on.exit(options(oldOpts))
? expr # lazily evaluate
?}
I wish R had more functions like this. This sort of behaviour is also useful when you open connections or change locales. Ruby's blocks provide nice syntactic sugar for this idea. Hadley
Assistant Professor / Dobelman Family Junior Chair Department of Statistics / Rice University http://had.co.nz/
Put together a list and we can see what might make sense. If we did take this on it would be good to think about providing a reasonable mechanism for addressing the small flaw in this function as it is defined here. Best, luke
On Wed, 27 Apr 2011, Hadley Wickham wrote:
This has the side effect of ignoring errors
and even hiding the error messages. ?If you
are concerned about multiple calls to on.exit()
in one function you could define a new function
like
?withOptions <- function(optionList, expr) {
? oldOpts <- options(optionList)
? on.exit(options(oldOpts))
? expr # lazily evaluate
?}
I wish R had more functions like this. This sort of behaviour is also useful when you open connections or change locales. Ruby's blocks provide nice syntactic sugar for this idea. Hadley
Luke Tierney
Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa Phone: 319-335-3386
Department of Statistics and Fax: 319-335-3017
Actuarial Science
241 Schaeffer Hall email: luke at stat.uiowa.edu
Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
Put together a list and we can see what might make sense. ?If we did take this on it would be good to think about providing a reasonable mechanism for addressing the small flaw in this function as it is defined here.
In devtools, I have:
#' Evaluate code in specified locale.
with_locale <- function(locale, expr) {
cur <- Sys.getlocale(category = "LC_COLLATE")
on.exit(Sys.setlocale(category = "LC_COLLATE", locale = cur))
Sys.setlocale(category = "LC_COLLATE", locale = locale)
force(expr)
}
(Using force here just to be clear about what's going on)
Bill discussed options(). Other ideas (mostly from skimming apropos("set")):
* graphics devices (i.e. automatic dev.off)
* working directory (as in the chdir argument to sys.source)
* environment variables (Sys.setenv/Sys.getenv)
* time limits (as replacement for transient = T)
For connections it would be nice to have something like:
with_connection <- function(con, expr) {
open(con)
on.exist(close(con))
force(expr)
}
but it's a little clumsy, because
with_connection(file("myfile.txt"), {do stuff...})
isn't very useful because you have no way to reference the connection
that you're using. Ruby's blocks have arguments which would require
big changes to R's syntax. One option would to use pronouns:
with_connection <- function(con, expr) {
open(con)
on.exist(close(con))
env <- new.env(parent = parent.frame()
env$.it <- con
eval(substitute(expr), env)
}
or anonymous functions:
with_connection <- function(con, f) {
open(con)
on.exist(close(con))
f(con)
}
Neither of which seems particularly appealing to me.
(I didn't test any of this code, so no guarantees that it works, but
hopefully you see the ideas)
Hadley
Assistant Professor / Dobelman Family Junior Chair Department of Statistics / Rice University http://had.co.nz/
From: h.wickham at gmail.com [mailto:h.wickham at gmail.com] On Behalf Of Hadley Wickham Sent: Wednesday, April 27, 2011 2:21 PM To: luke-tierney at uiowa.edu Cc: William Dunlap; r-help at r-project.org Subject: Re: [R] setting options only inside functions
Put together a list and we can see what might make sense. ?If we did take this on it would be good to think about providing a reasonable mechanism for addressing the small flaw in this function as it is defined here.
In devtools, I have: #' Evaluate code in specified locale.
S+ has a Sys.withlocale() that is a bit more general than
your with_locale():
> Sys.withlocale
function(expr, category = "LC_ALL", locale)
{
cur.locale <- Sys.getlocale(category)
on.exit(Sys.setlocale(category = category, locale = cur.locale))
Sys.setlocale(category = category, locale = locale)
expr
}
with_locale <- function(locale, expr) {
cur <- Sys.getlocale(category = "LC_COLLATE")
on.exit(Sys.setlocale(category = "LC_COLLATE", locale = cur))
Sys.setlocale(category = "LC_COLLATE", locale = locale)
force(expr)
}
(Using force here just to be clear about what's going on)
Bill discussed options(). Other ideas (mostly from skimming
apropos("set")):
* graphics devices (i.e. automatic dev.off)
Also, for setting and restoring graphics parameters with par().
* working directory (as in the chdir argument to sys.source) * environment variables (Sys.setenv/Sys.getenv) * time limits (as replacement for transient = T)
but it's a little clumsy, because
with_connection(file("myfile.txt"), {do stuff...})
isn't very useful because you have no way to reference the connection
that you're using. Ruby's blocks have arguments which would require
big changes to R's syntax. ?One option would to use pronouns:
Looking very much like python 'with' statements: http://effbot.org/zone/python-with-statement.htm Implemented via the 'with' statement which can operate on anything that has a __enter__ and an __exit__ method. Very neat. Barry
I would also love to see this implemented in R, as my current solution to the issue of doing tons of open/close, dev/dev.off, etc. is to use snippets in my IDE, and in the end I feel like it is a hack job. A pythonic "with" function would also solve most of the situations where I have had to use awkward try or tryCatch calls. I would be willing to help with this project, even if it is just testing. On Wed, Apr 27, 2011 at 5:43 PM, Barry Rowlingson
<b.rowlingson at lancaster.ac.uk> wrote:
but it's a little clumsy, because
with_connection(file("myfile.txt"), {do stuff...})
isn't very useful because you have no way to reference the connection
that you're using. Ruby's blocks have arguments which would require
big changes to R's syntax. ?One option would to use pronouns:
?Looking very much like python 'with' statements: http://effbot.org/zone/python-with-statement.htm ?Implemented via the 'with' statement which can operate on anything that has a __enter__ and an __exit__ method. Very neat. Barry
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
=============================================== Jon Daily Technician =============================================== #!/usr/bin/env outside # It's great, trust me.
1 day later
The Python solution does not extend, at least not cleanly, to things like dev on/ dev off or to Hadley's locale example. In any case if I am reading the Python source correctly on how they handle user interrupts this solution has the same non-robusness to user interrupts issue that Bill's initial solution had. As a basis I believe what we need is a mechanism that handles a setup, an action, and a cleanup, with setup and cleanup occurring with interrupts disablednand the action with interrupts enabled. Scheme's dynamic wind is similar, though I don't believe the scheme standard addresses interrupts and we don't need to worry about continuations, but some of the issues are similar. Probably we would want two flavors, one in which the action has to be a function that takes as a single argument the result produced by the setup code, and one in which the action can be an argument expression that is then evaluated at the appropriate place by laze evaluation. This can be done at the R level except for the controlling of interrupts (and possibly other asynchronous stuff)-- that would need a new pair of primitives (suspendInterrupts/enableInterupts or something like that). There is something in the Haskell literature on this that I have looked at a while back -- probably time to have another look.
On Thu, 28 Apr 2011, Jonathan Daily wrote:
I would also love to see this implemented in R, as my current solution to the issue of doing tons of open/close, dev/dev.off, etc. is to use snippets in my IDE, and in the end I feel like it is a hack job. A pythonic "with" function would also solve most of the situations where I have had to use awkward try or tryCatch calls. I would be willing to help with this project, even if it is just testing. On Wed, Apr 27, 2011 at 5:43 PM, Barry Rowlingson <b.rowlingson at lancaster.ac.uk> wrote:
but it's a little clumsy, because
with_connection(file("myfile.txt"), {do stuff...})
isn't very useful because you have no way to reference the connection
that you're using. Ruby's blocks have arguments which would require
big changes to R's syntax. ?One option would to use pronouns:
?Looking very much like python 'with' statements: http://effbot.org/zone/python-with-statement.htm ?Implemented via the 'with' statement which can operate on anything that has a __enter__ and an __exit__ method. Very neat. Barry
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Luke Tierney
Statistics and Actuarial Science
Ralph E. Wareham Professor of Mathematical Sciences
University of Iowa Phone: 319-335-3386
Department of Statistics and Fax: 319-335-3017
Actuarial Science
241 Schaeffer Hall email: luke at stat.uiowa.edu
Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
In python, opening a connection using with allows for a temporary
assignment using "as". So:
with file("/path/to/file") as con:
permanent_object = function(con)
would provide the return of function(con) globally, but close con. If
function(con) causes an error, con is still closed.
I agree with your description of what the function would need to do.
Would it make sense to make it generic and define default methods for
different setups? e.g. Using the current with/within when it is a
data.frame/environment, evaluating it when it is a function, etc.
On Fri, Apr 29, 2011 at 12:34 PM, <luke-tierney at uiowa.edu> wrote:
The Python solution does not extend, at least not cleanly, to things like dev on/ dev off or to Hadley's locale example. ?In any case if I am reading the Python source correctly on how they handle user interrupts this solution has the same non-robusness to user interrupts issue that Bill's initial solution had. As a basis I believe what we need is a mechanism that handles a setup, an action, and a cleanup, with setup and cleanup occurring with interrupts disablednand the action with interrupts enabled. Scheme's dynamic wind is similar, though I don't believe the scheme standard addresses interrupts and we don't need to worry about continuations, but some of the issues are similar. ?Probably we would want two flavors, one in which the action has to be a function that takes as a single argument the result produced by the setup code, and one in which the action can be an argument expression that is then evaluated at the appropriate place by laze evaluation. This can be done at the R level except for the controlling of interrupts (and possibly other asynchronous stuff)-- that would need a new pair of primitives (suspendInterrupts/enableInterupts or something like that). ?There is something in the Haskell literature on this that I have looked at a while back -- probably time to have another look. On Thu, 28 Apr 2011, Jonathan Daily wrote:
I would also love to see this implemented in R, as my current solution to the issue of doing tons of open/close, dev/dev.off, etc. is to use snippets in my IDE, and in the end I feel like it is a hack job. A pythonic "with" function would also solve most of the situations where I have had to use awkward try or tryCatch calls. I would be willing to help with this project, even if it is just testing. On Wed, Apr 27, 2011 at 5:43 PM, Barry Rowlingson <b.rowlingson at lancaster.ac.uk> wrote:
but it's a little clumsy, because
with_connection(file("myfile.txt"), {do stuff...})
isn't very useful because you have no way to reference the connection
that you're using. Ruby's blocks have arguments which would require
big changes to R's syntax. ?One option would to use pronouns:
?Looking very much like python 'with' statements: http://effbot.org/zone/python-with-statement.htm ?Implemented via the 'with' statement which can operate on anything that has a __enter__ and an __exit__ method. Very neat. Barry
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
-- Luke Tierney Statistics and Actuarial Science Ralph E. Wareham Professor of Mathematical Sciences University of Iowa ? ? ? ? ? ? ? ? ?Phone: ? ? ? ? ? ? 319-335-3386 Department of Statistics and ? ? ? ?Fax: ? ? ? ? ? ? ? 319-335-3017 ? Actuarial Science 241 Schaeffer Hall ? ? ? ? ? ? ? ? ?email: ? ? ?luke at stat.uiowa.edu Iowa City, IA 52242 ? ? ? ? ? ? ? ? WWW: ?http://www.stat.uiowa.edu
=============================================== Jon Daily Technician =============================================== #!/usr/bin/env outside # It's great, trust me.
-----Original Message----- From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of luke-tierney at uiowa.edu Sent: Friday, April 29, 2011 9:35 AM To: Jonathan Daily Cc: r-help at r-project.org; Hadley Wickham; Barry Rowlingson Subject: Re: [R] setting options only inside functions The Python solution does not extend, at least not cleanly, to things like dev on/ dev off or to Hadley's locale example. In any case if I am reading the Python source correctly on how they handle user interrupts this solution has the same non-robusness to user interrupts issue that Bill's initial solution had. As a basis I believe what we need is a mechanism that handles a setup, an action, and a cleanup, with setup and cleanup occurring with interrupts disablednand the action with interrupts enabled. Scheme's dynamic wind is similar, though I don't believe the scheme standard addresses interrupts and we don't need to worry about continuations, but some of the issues are similar. Probably we would want two flavors, one in which the action has to be a function that takes as a single argument the result produced by the setup code, and one in which the action can be an argument expression that is then evaluated at the appropriate place by laze evaluation. This can be done at the R level except for the controlling of interrupts (and possibly other asynchronous stuff)-- that would need a new pair of primitives (suspendInterrupts/enableInterupts or something like that). There is something in the Haskell literature on this that I have looked at a while back -- probably time to have another look.
Luke,
A similar problem is that if optionsList contains an illegal
option then setting options(optionList) will commit changes
to .Options as it works it way down the optionList until it
hits the illegal option, when it throws an error. Then the
following on.exit is never called (it wouldn't have the output
of options(optionList) to work on if it were called) and the
initial settings in optionList stick around forever. E.g.,
> withOptions <- function(optionList, expr) {
+ oldOpt <- options(optionList)
+ on.exit(options(oldOpt))
+ expr
+ }
> getOption("height")
NULL
> getOption("width")
[1] 80
> withOptions(list(height=10, width=-2), 666)
Error in options(optionList) :
invalid 'width' parameter, allowed 10...10000
> getOption("height")
[1] 10
> getOption("width")
[1] 80
I haven't checked to see if par() works in the same way - it
does in S+.
An ignoreInterrupts(expr) function would not help in that case.
Making options() (and par()) atomic operations would help, but that
may be a lot of work. options() might also warn but no change
.Options if there were an attempt to set an illegal option.
Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
On Thu, 28 Apr 2011, Jonathan Daily wrote:
I would also love to see this implemented in R, as my
current solution
to the issue of doing tons of open/close, dev/dev.off, etc.
is to use
snippets in my IDE, and in the end I feel like it is a hack job. A pythonic "with" function would also solve most of the
situations where
I have had to use awkward try or tryCatch calls. I would be
willing to
help with this project, even if it is just testing. On Wed, Apr 27, 2011 at 5:43 PM, Barry Rowlingson <b.rowlingson at lancaster.ac.uk> wrote:
but it's a little clumsy, because
with_connection(file("myfile.txt"), {do stuff...})
isn't very useful because you have no way to reference
the connection
that you're using. Ruby's blocks have arguments which
would require
big changes to R's syntax. ?One option would to use pronouns:
?Looking very much like python 'with' statements: http://effbot.org/zone/python-with-statement.htm ?Implemented via the 'with' statement which can operate on anything that has a __enter__ and an __exit__ method. Very neat. Barry
______________________________________________ R-help at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. -- Luke Tierney Statistics and Actuarial Science Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: luke at stat.uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu