[Rd] [External] DOCS/BUG?: opts <- base::.Options is *not* a copy

Martin Maechler m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Fri Feb 25 09:59:54 CET 2022


>>>>> Henrik Bengtsson 
>>>>>     on Thu, 24 Feb 2022 11:21:05 -0800 writes:

    > On Thu, Feb 24, 2022 at 5:23 AM <luke-tierney using uiowa.edu> wrote:
    >> 
    >> On Thu, 24 Feb 2022, Henrik Bengtsson wrote:
    >> 
    >> > Hi, is the following a non-documented feature or a bug:
    >> >
    >> > $ R --quiet --vanilla
    >> > opts <- base::.Options
    >> > opts[["abc"]]
    >> > #> NULL
    >> > options(abc = 42)
    >> > opts[["abc"]]
    >> > #> [1] 42
    >> >
    >> > I would have expected that 'opts' would be a *copy* of base::.Options
    >> > that is not affected by later changes to base::.Options.  FWIW, the
    >> > same happens if we try with:
    >> >
    >> > opts <- .BaseNamespaceEnv[[".Options"]]
    >> >
    >> > I don't think lazy evaluation is involved, because I evaluate
    >> > opts[["abc"]] above.
    >> >
    >> > The only thing help(".Options") says is:
    >> >
    >> > Note:
    >> > For compatibility with S there is a visible object .Options whose
    >> > value is a pairlist containing the current options() (in no particular
    >> > order). Assigning to it will make a local copy and not change the
    >> > original. (Using it however is faster than calling options()).
    >> 
    >> You are misreading what this says. As with any assignment to an object
    >> that has other references, the assignment will create a local copy
    >> before mutating.

    > I don't think I misread it; that's exactly how I interpreted it, too.
    > I just copied that passage to help the reader see that there's nothing
    > in the docs mentioning this behavior.

    >> It does not say that referencing the object makes a
    >> copy. So there is no inconsistency.

    > I'd argue that this behavior of .Options (because of how options() is
    > implemented) is not a standard procedure in R, and that the
    > expectation would be to make a copy unless otherwise documented. You
    > need to dig into the code to figure out that this is not the case and
    > how it works.  For example, my mental model of how this is implemented
    > is something like:

    > .Options <- pairlist()
    > options <- function(...) {
    > args <- list(...)
    > old <- new <- .Options
    > for (name in names(args)) new[[name]] <- args[[name]]
    > assignInMyNamespace(".Options", new)
    > invisible(old)
    > }

    > and that does create a copy.

    > I only discovered this because I added the following to my package tests:

    > opts <- base::.Options
    > call_random_fcn()
    > stopifnot(identical(base::.Options, opts))

    > Turns out it never failed. I use .Options, because it's faster than
    > options(), which always sorts elements by their names.  FWIW, the
    > workaround is to force a copy using opts <- as.list(base::.Options).

Esthetics only:  I think I'd rather use

   opts <- force(base::.Options)



    >> That options() modifies the value of an object with multiple
    >> references is not ideal, but changing that while maintaining .Object
    >> as a regular variable is probably more trouble than it is worth. It is
    >> probably time to work towards deprecating .Options (maybe turning it
    >> into an active binding that does make a copy). At the very least
    >> discouraging its use in the help file.

    > This sounds good to me.

We might consider  `options()` gaining an optional argument, say
`sortNames = TRUE`  and  `options(sortNames=FALSE)` would still not
sort and hence be faster than pure options()

Martin



    > Thanks,

    > Henrik

    >> 
    >> Other that changing the docs I doubt this will ever get high enough on
    >> anyone's priority list to get done
    >> 
    >> Best,
    >> 
    >> luke
    >> 
    >> >
    >> > This behavior goes back to at least R 2.15.0.
    >> >
    >> > /Henrik
    >> >
    >> > ______________________________________________
    >> > R-devel using r-project.org mailing list
    >> > https://stat.ethz.ch/mailman/listinfo/r-devel
    >> >
    >> 
    >> --
    >> Luke Tierney
    >> 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-tierney using uiowa.edu
    >> Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu

    > ______________________________________________
    > R-devel using r-project.org mailing list
    > https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list