[R] how to override/replace a function in a package namespace?

Henrik Bengtsson hb at stat.berkeley.edu
Tue Aug 19 01:29:46 CEST 2008


Hi,

see reassignInPackage() of R.utils - that's where the code snipped
comes from.  I wrote that so that I could patch/optimize certain
function (before they where patch in the public release).  I haven't
used it to patch S4 methods, so I don't know it will work for them.
Here is an example of how to use it:

> library(R.utils);
> orgQuit <- base::quit;
> myQuit <- function(...) { cat("QUITTING R!\n"); orgQuit(...); }
> reassignInPackage("quit", pkgName="base", myQuit);
> quit()
QUITTING R!
Save workspace image? [y/n/c]: c
> quit
function(...) { cat("QUITTING R!\n"); orgQuit(...); }
<environment: namespace:base>
attr(,"oldValue")
function (save = "default", status = 0, runLast = TRUE)
.Internal(quit(save, status, runLast))
<environment: namespace:base>
>

Note that in order for reassignInPackage() to work there must be an
existing object that is replace, hence the prefix "reassign".

Maybe this will help you

/Henrik

On Mon, Aug 18, 2008 at 8:10 AM, Ben Bolker <bolker at ufl.edu> wrote:
> Henrik Bengtsson <hb <at> stat.berkeley.edu> writes:
>
>>
>> The few times I want to patch a function like this, I use:
>>
>>   unlockBinding(name, env);
>>   assignInNamespace(name, value, ns=pkgName, envir=env);
>>   assign(name, value, envir=env);
>>   lockBinding(name, env);
>>
>> /Henrik
>>
>
>  OK, I admit that I don't get it.
>  I eventually managed to figure out that I needed the
> environment corresponding to getNamespace("package")
> in this case, not the one corresponding to
> as.environment("package"), but I still seem to
> be doing something wrong (perhaps I'm following the
> recipe too mindlessly).
>
>  The goal here is to replace a bit of code
> that uses parent.frame(2) with parent.frame(1) --
> that's what my "rjhack.file" does.
>
>
> tstf <- function() {
>  print(environment(jags))
>  a = grep("get,",deparse(jags),value=TRUE)  ## parent.frame(2)
>  length(grep("1",a))>0
> }
>
> library(R2jags)
> tstf()
>
> rjhack.file <- "~/lib/R/pkgs/mixstock/pkg/inst/myjags.R"
> source(rjhack.file)  ## read hacked version into global workspace
> tstf()
> RJ <- getNamespace("R2jags")
> ## attempt to replace package version with hacked version ...
> unlockBinding("jags", RJ)
> assignInNamespace("jags",jags,ns="R2jags", envir=RJ)
> assign("jags", jags, envir=RJ)
> lockBinding("jags",RJ)
> rm(jags) ## get rid of global copy
>
>
>  I'm beginning to feel it would be a lot easier
> to build my own local copy of the package ... in
> what way am I being a bonehead?
>
> library(fortunes)
> gsub("S4 methods","namespaces",fortune("S4")[1])
>
>  thanks
>    Ben Bolker
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>



More information about the R-help mailing list