Re: [Rd] invisible functions

2018-10-17 Thread Duncan Murdoch

On 17/10/2018 11:16 AM, S Ellison wrote:

2.  change cfun[[1]] <- quote(cord.work) to cfun[[1]] <-
quote(survival:::cord.work).  You say this will mess up your test bed.
That suggests that your test bed is broken.  This is a perfectly legal
and valid solution.

Valid in a package, but forces code to call a loaded library version of a 
function rather than (say) a 'source'd user-space version that is under 
development.
Being non-specific (ie omitting foo:::) means that test code would pick up the 
development version in the current user environment by default. That's handy 
for small mods.


I generally rebuild a package after each change.  In RStudio that's 
pretty simple:  "Install and Restart" saves the current workspace, shuts 
down R, installs the revised package, and restarts R with the old 
workspace.  It's all pretty quick.


Duncan Murdoch

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


Re: [Rd] invisible functions

2018-10-17 Thread S Ellison
> 2.  change cfun[[1]] <- quote(cord.work) to cfun[[1]] <-
> quote(survival:::cord.work).  You say this will mess up your test bed.
> That suggests that your test bed is broken.  This is a perfectly legal
> and valid solution.
Valid in a package, but forces code to call a loaded library version of a 
function rather than (say) a 'source'd user-space version that is under 
development. 
Being non-specific (ie omitting foo:::) means that test code would pick up the 
development version in the current user environment by default. That's handy 
for small mods.


S Ellison



***
This email and any attachments are confidential. Any use, copying or
disclosure other than by the intended recipient is unauthorised. If 
you have received this message in error, please notify the sender 
immediately via +44(0)20 8943 7000 or notify postmas...@lgcgroup.com 
and delete this message and any copies from your computer and network. 
LGC Limited. Registered in England 2991879. 
Registered office: Queens Road, Teddington, Middlesex, TW11 0LY, UK
__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] invisible functions

2018-10-16 Thread Duncan Murdoch

On 16/10/2018 6:42 PM, Therneau, Terry M., Ph.D. via R-devel wrote:

The survival package, like many others, has several helper functions that are 
not declared
in the namespace, since their only use is to be called by other "main" 
functions of the
package.  This works well since the functions in the survival namespace can see 
them ---
without ::: arguments --- and others don't.

Until a situation I ran into this week, for which I solicit comments or advice. 
  The
concordance function is a new addition, and it has one case where the same 
underlying
helper function is called multiple times, with many arguments passed through 
from the
parent.  I thought that this would be a good use for the trick we use for 
model.frame, so
I have code like this:

concordance.coxph <- function(fit, ..., newdata, group, ymin, ymax,
     timewt=c("n", "S", "S/G", "n/G", "n/G2"),
     influence=0, ranks=FALSE, timefix=TRUE) {
      Call <- match.call()
      .
      .
      .
      cargs <- c("ymin", "ymax","influence", "ranks", "timewt", "timefix")
      cfun <- Call[c(1, match(cargs, names(Call), nomatch=0))]
      cfun[[1]] <- quote(cord.work)
      cfun$reverse <- TRUE
      rval <- eval(cfun, parent.frame())

This worked fine in my not-in-a-namespace test bed, but then fails when 
packaged up for
real: the code can't find the helper function cord.work!  The rule that 
survival package
functions can "see" their undeclared helpers fails.


The reason that fails is as follows:

cfun, despite its name, is not a function.  It's an unevaluated expression.

You are evaluating it in parent.frame(), which is the caller's 
evaluation frame.  That frame can't generally see the private frame for 
your package.


Since it needs to see things supplied by the user, it needs to see 
parent.frame.  It doesn't need to see anything in your evaluation frame 
other than cord.work, but it can't see that, which is your problem.


I think there are at least two choices:

1.  change cfun[[1]] <- quote(cord.work) to cfun[[1]] <- cord.work. 
This should work, but error messages may be messed up, because you'll be 
calling an anonymous function that is a copy of cord.work, rather than 
calling cord.work by name.


2.  change cfun[[1]] <- quote(cord.work) to cfun[[1]] <- 
quote(survival:::cord.work).  You say this will mess up your test bed. 
That suggests that your test bed is broken.  This is a perfectly legal 
and valid solution.


Duncan Murdoch



I got it working by changing parent.frame() to environment(concordance) in the 
eval()
call.   Since everything used by cord.work is explicitly passed in its argument 
list this
does work.

Comments or suggestions?   (I avoid having survival:: in the survival package 
because it
messes up my particular test bed.)

Terry


[[alternative HTML version deleted]]

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



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


[Rd] invisible functions

2018-10-16 Thread Therneau, Terry M., Ph.D. via R-devel
The survival package, like many others, has several helper functions that are 
not declared 
in the namespace, since their only use is to be called by other "main" 
functions of the 
package.  This works well since the functions in the survival namespace can see 
them --- 
without ::: arguments --- and others don't.

Until a situation I ran into this week, for which I solicit comments or advice. 
  The 
concordance function is a new addition, and it has one case where the same 
underlying 
helper function is called multiple times, with many arguments passed through 
from the 
parent.  I thought that this would be a good use for the trick we use for 
model.frame, so 
I have code like this:

concordance.coxph <- function(fit, ..., newdata, group, ymin, ymax,
    timewt=c("n", "S", "S/G", "n/G", "n/G2"),
    influence=0, ranks=FALSE, timefix=TRUE) {
     Call <- match.call()
     .
     .
     .
     cargs <- c("ymin", "ymax","influence", "ranks", "timewt", "timefix")
     cfun <- Call[c(1, match(cargs, names(Call), nomatch=0))]
     cfun[[1]] <- quote(cord.work)
     cfun$reverse <- TRUE
     rval <- eval(cfun, parent.frame())

This worked fine in my not-in-a-namespace test bed, but then fails when 
packaged up for 
real: the code can't find the helper function cord.work!  The rule that 
survival package 
functions can "see" their undeclared helpers fails.

I got it working by changing parent.frame() to environment(concordance) in the 
eval() 
call.   Since everything used by cord.work is explicitly passed in its argument 
list this 
does work.

Comments or suggestions?   (I avoid having survival:: in the survival package 
because it 
messes up my particular test bed.)

Terry


[[alternative HTML version deleted]]

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