Re: [R-pkg-devel] Is there a better way ...?

2021-10-21 Thread Andrew Simmons
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  wrote:

>
> On Thu, 21 Oct 2021 02:03:41 -0400
> Duncan Murdoch  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]]

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Is there a better way ...?

2021-10-21 Thread Martin Maechler
> Duncan Murdoch 
> on Thu, 21 Oct 2021 08:09:02 -0400 writes:

> I agree with almost everything Deepayan said, but would add one thing:
> On 21/10/2021 3:41 a.m., Deepayan Sarkar wrote:
> ...

>> My suggestion is having a package-specific environment, and Duncan's
>> is to have a function-specific environment. If you only need this for
>> this one function, then that should be good enough. If you eventually
>> want to access the persistent information from multiple functions,
>> having a package-specific environment would be more useful.

> I agree with that statement, but those aren't the only two choices. 
> Your local() call can create several functions and return them in a 
> list; then just those functions have access to the local variables.  For 
> example,

> createFns <- local({

> .fooInfo <- NULL

> fn1 <- function (...) { ... }
> fn2 <- function (...) { ... }

> list(fn1 = fn1, fn2 = fn2)
> })

> fns <- createFns()
> fn1 <- fns$fn1
> fn2 <- fns$fn2

> Now fn1 and fn2 are functions that can see .fooInfo, and nobody else can 
> (without going through contortions).

> One other difference between this approach and the package-specific 
> environment:  there's only one package-specific environment in 
> Deepayan's formulation, but I could call createFns() several times, 
> creating several pairs of functions, each pair with its own independent 
> version of .fooInfo.

> I don't know if that's something that would be useful to you, but 
> conceivably you'd want to maintain partial plots in several different 
> windows, and that would allow you to do so.

Note that the above approach has been how  nls()  has been
implemented for R ... a very long time ago {before R 1.0.0}

e.g. from  example(nls) :

DNase1 <- subset(DNase, Run == 1)
fm1 <- nls(density ~ SSlogis(log(conc), Asym, xmid, scal), DNase1)
str(fm1 $ m)
> List of 16
>  $ resid :function ()  
>  $ fitted:function ()  
>  $ formula   :function ()  
>  $ deviance  :function ()  
>  $ lhs   :function ()  
>  $ gradient  :function ()  
>  $ conv  :function ()  
>  $ incr  :function ()  
>  $ setVarying:function (vary = rep_len(TRUE, np))  
>  $ setPars   :function (newPars)  
>  $ getPars   :function ()  
>  $ getAllPars:function ()  
>  $ getEnv:function ()  
>  $ trace :function ()  
>  $ Rmat  :function ()  
>  $ predict   :function (newdata = list(), qr = FALSE)  
>  - attr(*, "class")= chr "nlsModel"

## so 16 functions, all sharing the *same* environment very
## efficiently and nicely

## this is *the* environment for the fitted model :
fmE <- environment(fm1$m[[1]])
ls.str(fmE)
> convCrit : function ()  
> dev :  num 0.00479
> env :  
> form : Class 'formula'  language density ~ SSlogis(log(conc), Asym, xmid, 
> scal)
> getPars : function ()  
>  
>  
>  

so the environment "contains" the functions themselves (but quite
a few more things) and for an environment that means it only
has pointers to the same function objects which are *also* in  `fm1$m`.

So, there has been a nice convincing and important example on
how to do this - inside R for more than two decennia.

Martin Maechler

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Is there a better way ...?

2021-10-21 Thread Duncan Murdoch

I agree with almost everything Deepayan said, but would add one thing:


On 21/10/2021 3:41 a.m., Deepayan Sarkar wrote:
 ...


My suggestion is having a package-specific environment, and Duncan's
is to have a function-specific environment. If you only need this for
this one function, then that should be good enough. If you eventually
want to access the persistent information from multiple functions,
having a package-specific environment would be more useful.


I agree with that statement, but those aren't the only two choices. 
Your local() call can create several functions and return them in a 
list; then just those functions have access to the local variables.  For 
example,


createFns <- local({

   .fooInfo <- NULL

   fn1 <- function (...) { ... }
   fn2 <- function (...) { ... }

   list(fn1 = fn1, fn2 = fn2)
})

fns <- createFns()
fn1 <- fns$fn1
fn2 <- fns$fn2

Now fn1 and fn2 are functions that can see .fooInfo, and nobody else can 
(without going through contortions).


One other difference between this approach and the package-specific 
environment:  there's only one package-specific environment in 
Deepayan's formulation, but I could call createFns() several times, 
creating several pairs of functions, each pair with its own independent 
version of .fooInfo.


I don't know if that's something that would be useful to you, but 
conceivably you'd want to maintain partial plots in several different 
windows, and that would allow you to do so.


And there are other choices too:  there are several packages 
implementing object systems that allow objects to maintain persistent 
data.   I haven't used those, so this list may contain omissions and 
errors:  R6, R.oo, proto.


Duncan Murdoch

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Is there a better way ...?

2021-10-21 Thread Deepayan Sarkar
On Thu, Oct 21, 2021 at 12:15 PM Rolf Turner  wrote:
>
>
> On Thu, 21 Oct 2021 02:03:41 -0400
> Duncan Murdoch  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?

My suggestion is having a package-specific environment, and Duncan's
is to have a function-specific environment. If you only need this for
this one function, then that should be good enough. If you eventually
want to access the persistent information from multiple functions,
having a package-specific environment would be more useful.

I'm not sure what you are trying to do, but I can't see how you can do
something sensible with a function-specific environment if someone
does

plot.foo(something)
plot.default(1:10)
plot.foo(something else, add = TRUE)

So maybe you would eventually want to set a hook (?setHook) for
plot.new to ensure that no other plot has been created in between,
which could write into this package-specific environment.

> 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.

Nothing other than the usual reason for not exporting things
unnecessarily, which is to not pollute the user workspace.

> 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! :-)

Andrew's suggestion looks more complicated than it is. Think of
.fooInfo as a "global" variable, just in your package namespace rather
than .GlobalEnv, so you could do (in your package code)

.fooInfo <- NULL

plot.foo <- function(...)
{
   if (is.null(.fooInfo)) ... # use .fooInfo
   .fooInfo <<- something # set .fooInfo
}

Andrew suggested a separate (and unnamed) environment to store both
.fooInfo and plot.foo, so the setting part becomes a bit more
complicated (but accessing becomes safer in the sense that no other
function can access .fooInfo).

My suggestion is essentially similar, except that you can use <-
instead of <<- because it's an environment.

.fooEnv <- new.env()

plot.foo <- function(...)
{
   if (is.null(.fooEnv$info)) ... # use .fooEnv$info
   .fooEnv$info <- something # set .fooEnv$info
}

Best,
-Deepayan

> Thanks again everybody.
>
> cheers,
>
> Rolf
>
> --
> Honorary Research Fellow
> Department of Statistics
> University of Auckland
> Phone: +64-9-373-7599 ext. 88276
>

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Is there a better way ...?

2021-10-21 Thread Rolf Turner


On Thu, 21 Oct 2021 02:03:41 -0400
Duncan Murdoch  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

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Is there a better way ...?

2021-10-21 Thread Duncan Murdoch

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).


Duncan Murdoch




On Thu, Oct 21, 2021 at 12:29 AM Rolf Turner 
wrote:



I have a plot method (say plot.foo()) that I want to be able to call so
that if argument "add" is set equal to TRUE, then further structure will
be added to the same plot.  This is to be used *only* in the context in
which the plot being added to was created using plot.foo().

[Please don't ask me why I don't do everything in a single call to
plot.foo().  There *are* reasons.]

In order to make sure that the "further structure" has the appropriate
form, the call to plot.foo(...,add=TRUE,...) needs to access information
about what was done in the previous call to plot.foo().

Initially I tried to effect this by creating, in a call of the form
plot.foo(...,add=FALSE,...), an object, say ".fooInfo", in the global
environment, and then having the call plot.foo(...,add=TRUE,...)
access the necessary information from ".fooInfo".

It all worked OK, but when I built my package for Windoze, using
win-builder, I got a note of the form:


NOTE
Found the following assignment to the global environment:
File 'pckgename/R/plot.foo.R':
   assign(".fooInfo", fooInfo, pos = 1)


I thought uh-oh; CRAN will kick up a stink if/when I submit my package.

I think I've figured out a work-around using tempfile().  There
are difficulties in that tempfile() creates unique names by tacking
on an alpha-numeric string such as "38348397e595c" to the file name
that I specify, so the call to plot.foo(...,add=TRUE,...) cannot know
the *exact* file name.  I think I can get around that by grepping on
"fooInfo" in list.files(tempdir()).  I also need to make sure that
I unlink() any old instances of files in tempdir() with the string
"fooInfo" in their names before creating a new instance.  Elsewise
ambiguities will ensue.

As I say --- I think this can all be made to work.  But 
Am I missing some "obvious" strategy?  I.e. is there a
better/simpler/less convoluted way of handling this problem?

Grateful for any pearls of wisdom.

cheers,

Rolf Turner

--
Honorary Research Fellow
Department of Statistics
University of Auckland
Phone: +64-9-373-7599 ext. 88276

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel



[[alternative HTML version deleted]]

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel



__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Is there a better way ...?

2021-10-20 Thread Andrew Simmons
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.

On Thu, Oct 21, 2021 at 12:29 AM Rolf Turner 
wrote:

>
> I have a plot method (say plot.foo()) that I want to be able to call so
> that if argument "add" is set equal to TRUE, then further structure will
> be added to the same plot.  This is to be used *only* in the context in
> which the plot being added to was created using plot.foo().
>
> [Please don't ask me why I don't do everything in a single call to
> plot.foo().  There *are* reasons.]
>
> In order to make sure that the "further structure" has the appropriate
> form, the call to plot.foo(...,add=TRUE,...) needs to access information
> about what was done in the previous call to plot.foo().
>
> Initially I tried to effect this by creating, in a call of the form
> plot.foo(...,add=FALSE,...), an object, say ".fooInfo", in the global
> environment, and then having the call plot.foo(...,add=TRUE,...)
> access the necessary information from ".fooInfo".
>
> It all worked OK, but when I built my package for Windoze, using
> win-builder, I got a note of the form:
>
> > NOTE
> > Found the following assignment to the global environment:
> > File 'pckgename/R/plot.foo.R':
> >   assign(".fooInfo", fooInfo, pos = 1)
>
> I thought uh-oh; CRAN will kick up a stink if/when I submit my package.
>
> I think I've figured out a work-around using tempfile().  There
> are difficulties in that tempfile() creates unique names by tacking
> on an alpha-numeric string such as "38348397e595c" to the file name
> that I specify, so the call to plot.foo(...,add=TRUE,...) cannot know
> the *exact* file name.  I think I can get around that by grepping on
> "fooInfo" in list.files(tempdir()).  I also need to make sure that
> I unlink() any old instances of files in tempdir() with the string
> "fooInfo" in their names before creating a new instance.  Elsewise
> ambiguities will ensue.
>
> As I say --- I think this can all be made to work.  But 
> Am I missing some "obvious" strategy?  I.e. is there a
> better/simpler/less convoluted way of handling this problem?
>
> Grateful for any pearls of wisdom.
>
> cheers,
>
> Rolf Turner
>
> --
> Honorary Research Fellow
> Department of Statistics
> University of Auckland
> Phone: +64-9-373-7599 ext. 88276
>
> __
> R-package-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>

[[alternative HTML version deleted]]

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


Re: [R-pkg-devel] Is there a better way ...?

2021-10-20 Thread Deepayan Sarkar
On Thu, Oct 21, 2021 at 9:59 AM Rolf Turner  wrote:
>
>
> I have a plot method (say plot.foo()) that I want to be able to call so
> that if argument "add" is set equal to TRUE, then further structure will
> be added to the same plot.  This is to be used *only* in the context in
> which the plot being added to was created using plot.foo().
>
> [Please don't ask me why I don't do everything in a single call to
> plot.foo().  There *are* reasons.]
>
> In order to make sure that the "further structure" has the appropriate
> form, the call to plot.foo(...,add=TRUE,...) needs to access information
> about what was done in the previous call to plot.foo().
>
> Initially I tried to effect this by creating, in a call of the form
> plot.foo(...,add=FALSE,...), an object, say ".fooInfo", in the global
> environment, and then having the call plot.foo(...,add=TRUE,...)
> access the necessary information from ".fooInfo".

Why not have a private (unexported) environment in your own package
for the same purpose? (That's the strategy used by lattice.) E.g., in
your zzz.R

.FooEnv <- new.env()

and then have your plot.foo write into / read from that. Long term, it
may be better to write accessor functions (which can still be
unexported if only used by your package code) if you want an
implementation-agnostic interface.

Best,
-Deepayan

> It all worked OK, but when I built my package for Windoze, using
> win-builder, I got a note of the form:
>
> > NOTE
> > Found the following assignment to the global environment:
> > File 'pckgename/R/plot.foo.R':
> >   assign(".fooInfo", fooInfo, pos = 1)
>
> I thought uh-oh; CRAN will kick up a stink if/when I submit my package.
>
> I think I've figured out a work-around using tempfile().  There
> are difficulties in that tempfile() creates unique names by tacking
> on an alpha-numeric string such as "38348397e595c" to the file name
> that I specify, so the call to plot.foo(...,add=TRUE,...) cannot know
> the *exact* file name.  I think I can get around that by grepping on
> "fooInfo" in list.files(tempdir()).  I also need to make sure that
> I unlink() any old instances of files in tempdir() with the string
> "fooInfo" in their names before creating a new instance.  Elsewise
> ambiguities will ensue.
>
> As I say --- I think this can all be made to work.  But 
> Am I missing some "obvious" strategy?  I.e. is there a
> better/simpler/less convoluted way of handling this problem?
>
> Grateful for any pearls of wisdom.
>
> cheers,
>
> Rolf Turner
>
> --
> Honorary Research Fellow
> Department of Statistics
> University of Auckland
> Phone: +64-9-373-7599 ext. 88276
>
> __
> R-package-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-package-devel

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel


[R-pkg-devel] Is there a better way ...?

2021-10-20 Thread Rolf Turner


I have a plot method (say plot.foo()) that I want to be able to call so
that if argument "add" is set equal to TRUE, then further structure will
be added to the same plot.  This is to be used *only* in the context in
which the plot being added to was created using plot.foo().

[Please don't ask me why I don't do everything in a single call to
plot.foo().  There *are* reasons.]

In order to make sure that the "further structure" has the appropriate
form, the call to plot.foo(...,add=TRUE,...) needs to access information
about what was done in the previous call to plot.foo().

Initially I tried to effect this by creating, in a call of the form
plot.foo(...,add=FALSE,...), an object, say ".fooInfo", in the global
environment, and then having the call plot.foo(...,add=TRUE,...)
access the necessary information from ".fooInfo".

It all worked OK, but when I built my package for Windoze, using
win-builder, I got a note of the form:

> NOTE
> Found the following assignment to the global environment:
> File 'pckgename/R/plot.foo.R':
>   assign(".fooInfo", fooInfo, pos = 1)

I thought uh-oh; CRAN will kick up a stink if/when I submit my package.

I think I've figured out a work-around using tempfile().  There
are difficulties in that tempfile() creates unique names by tacking
on an alpha-numeric string such as "38348397e595c" to the file name
that I specify, so the call to plot.foo(...,add=TRUE,...) cannot know
the *exact* file name.  I think I can get around that by grepping on
"fooInfo" in list.files(tempdir()).  I also need to make sure that
I unlink() any old instances of files in tempdir() with the string
"fooInfo" in their names before creating a new instance.  Elsewise
ambiguities will ensue.

As I say --- I think this can all be made to work.  But 
Am I missing some "obvious" strategy?  I.e. is there a
better/simpler/less convoluted way of handling this problem?

Grateful for any pearls of wisdom.

cheers,

Rolf Turner

-- 
Honorary Research Fellow
Department of Statistics
University of Auckland
Phone: +64-9-373-7599 ext. 88276

__
R-package-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel