[R-pkg-devel] Is there a better way ...?
Andrew Simmons
@kw@|mmo @end|ng |rom gm@||@com
Thu Oct 21 16:45:02 CEST 2021
Duncan's version is much clearer than my solution, and the only reason I
use my version is so that the source reference of the function looks
neater, and so that auto-code-indentation won't mess up my source reference
either.
If none of that made sense, don't worry about it, use Duncan's approach.
I think the advantage of Duncan's solution is that getting and setting
.fooInfo is more compact.
It's not clear exactly how you're modifying .fooInfo, but I'll assume
plot.foo is modifying it. Using Duncan's approach, you might do something
like:
plot.foo <- local({
.fooInfo <- 0
function (...)
{
value <- .fooInfo # get .fooInfo
.fooInfo <<- .fooInfo + 1 # set .fooInfo, you must use <<- here
instead of <-
return(value)
}
})
and Deepayan's approach:
..foo.env <- local({
.fooInfo <- 0
environment()
})
plot.foo <- function (...)
{
value <- .foo.env$.fooInfo # get .fooInfo
.foo.env$.fooInfo <- .foo.env$.fooInfo + 1 # set .fooInfo
return(value)
}
Both of these work perfectly fine, so you don't have to worry too much
about which you implement. The differences are mostly just visual
appearance, they have nearly equivalent functionality and performance.
On Thu, Oct 21, 2021 at 2:45 AM Rolf Turner <r.turner using auckland.ac.nz> wrote:
>
> On Thu, 21 Oct 2021 02:03:41 -0400
> Duncan Murdoch <murdoch.duncan using gmail.com> wrote:
>
> > On 21/10/2021 12:40 a.m., Andrew Simmons wrote:
> > > I think the simplest answer is to store the variable in the
> > > functions frame. I'm assuming here that the only plot.foo needs
> > > access to .fooInfo, if not this can be changed.
> > >
> > >
> > > plot.foo <- function (...)
> > > {
> > > .fooInfo
> > > }
> > > environment(plot.foo) <- new.env()
> > > evalq({
> > > .fooInfo <- NULL
> > > }, environment(plot.foo))
> > >
> > >
> > > Make your function, and do whatever you need with .fooInfo within
> > > said function. Whenever you previously updated .fooInfo in the
> > > global environment, update .fooInfo in plot.foo environment instead.
> > > Also, because .fooInfo is not stored in the package's frame, it
> > > won't be locked when the namespace is sealed. If you created it at
> > > the toplevel, that would create some issues. But this works fine.
> >
> > I agree with the final result, but I'd write the code differently:
> >
> > plot.foo <- local({
> >
> > .fooInfo <- NULL
> >
> > function (...) { ... }
> > })
> >
> > creates an environment, puts .fooInfo into it with value NULL, then
> > creates a function with that environment attached and returns it.
> >
> > I think Andrew's approach will work, but changing a function's
> > environment always worries me. Using local(), the function assigned
> > to plot.foo never has a different environment than the one it ends up
> > with (and I don't need to remember how evalq() works).
>
> Thanks everyone for these suggestions. They seem a great deal
> less shaganappi/kludgy than my previous approaches.
>
> I've never really felt totally comfortable with the environment
> concept, despite have used it quite a bit (basically in a
> hammer-and-hope style.)
>
> Can anyone comment on the difference between Deepayan's suggestion
> (create a new environment in the package) and Duncan's suggestion
> (create an environment that is local to plot.foo())? Are there pros
> and cons between the two?
>
> And Deepayan: what is the rationale for not exporting the new
> environment that you suggest creating? Presumably this guards against
> something. What? I'd just like to extend my (currently minimal)
> comprehension of the issues.
>
> I must admit that Andrew's suggestion kind of overwhelms and bewilders
> me. I really have no idea what evalq() does. I guess I could RTFM,
> but the thought of doing that scares me! :-)
>
> Thanks again everybody.
>
> cheers,
>
> Rolf
>
> --
> Honorary Research Fellow
> Department of Statistics
> University of Auckland
> Phone: +64-9-373-7599 ext. 88276
>
>
[[alternative HTML version deleted]]
More information about the R-package-devel
mailing list