[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