r - retrieve original version of package function even if over-assigned -


suppose replace function of package, example knitr:::sub_ext. (note: i'm particularly interested internal function, i.e. accessible ::: opposed ::, same answer may work both).

library(knitr) my.sub_ext <- function (x, ext) {     return("i'm in package stealing functions d:") } # replace knitr:::sub_ext my.sub_ext knitr <- asnamespace('knitr') unlockbinding('sub_ext', knitr) assign('sub_ext', my.sub_ext, knitr) lockbinding('sub_ext', knitr) 

question: there way retrieve original knitr:::sub_ext after i've done this? preferably without reloading package?


(i know people want know why want here is. not required reading question). i've been patching functions in packages (not sub_ext function...):

original.sub_ext <- knitr:::sub_ext new.sub_ext <- function (x, ext) {     # code first, e.g.     x <- do.something.with(x)     # call original knitr:::sub_ext     original.sub_ext(x, ext) } # set knitr:::sub_ext new.sub_ext before. 

i agree not in general idea (in cases these quick fixes until changes make way cran, or "feature requests" never approved because case-specific).

the problem above if accidentally execute twice (e.g. it's @ top of script run twice without restarting r in between), on second time original.sub_ext previous new.sub_ext opposed real knitr:::sub_ext, infinite recursion.

since sub_ext internal function (i wouldn't call directly, functions knitr knit call internally), can't hope modify functions call sub_ext call new.sub_ext manually, hence approach of replacing definition in package namespace.

when assign('sub_ext', my.sub_ext, knitr), irrevocably overwriting value associated sub_ext value of my.sub_ext. if first stash original value, though, it's not hard reset when you're done:

library(knitr) knitr <- asnamespace("knitr")  ## store original value of sub_ext .sub_ext <- get("sub_ext", envir = knitr)  ## overwrite own function my.sub_ext <- function (x, ext) "i'm in package stealing functions d:" assigninnamespace('sub_ext', my.sub_ext, knitr) knitr:::sub_ext("eg.csv", "pdf") # [1] "i'm in package stealing functions d:"  ## reset when you're done assigninnamespace('sub_ext', .sub_ext, knitr) knitr:::sub_ext("eg.csv", "pdf") # [1] "eg.pdf"    

alternatively, long adding lines of code what's there, add code using trace(). what's nice trace() that, when done, can use untrace() revert function's body original form:

trace(what = "mean.default",        tracer = quote({           <- 1           b <- 2           x <- x*(a+b)       }),        @ = 1) mean(1:2) # tracing mean.default(1:2) step 1  # [1] 4.5 untrace("mean.default") # untracing function "mean.default" in package "base" mean(1:2) # [1] 1.5 

note if function tracing in namespace, you'll want use trace()'s where argument, passing name of other (exported) function shares to-be-traced function's namespace. so, trace unexported function in knitr's namespace, set where=knit


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

qt - Errors in generated MOC files for QT5 from cmake -