I am working on a tool for R and I can't figure out how to replace S3 methods inside packages. Let's take print.aov for example. I want to replace its body, but inside stats namespace. If I just reassign the function in the namespace
> reassignInEnv <- function(name, obj, env) { if (exists(name, env)) { if (bindingIsLocked(name, env)) { unlockBinding(name, env) assign(name, obj, envir = env) lockBinding(name, env) } else { assign(name, obj, envir = env) } } else { stop("Object does not exist") } } > reassignInEnv("print.aov", function(x, ...) { print("replaced function!") }, env = getNamespace('stats')) Previously registered function will be called when print dispatches, instead of a new one.
> print(aov(yield ~ block + N * P + K, npk)) Call: aov(formula = yield ~ block + N * P + K, data = npk) Terms: block N P K N:P Residuals Sum of Squares 343.2950 189.2817 8.4017 95.2017 21.2817 218.9033 Deg. of Freedom 5 1 1 1 1 14 Residual standard error: 3.954232 Estimated effects may be unbalanced I also tried R.methodsS3 package, but it won't work, because it tries to do an assignment in a locked environment.
> unlockBinding("print.aov", getNamespace('stats')) > setMethodS3(name = "print", definition = function(x, ...) { print("replaced function!") }, class = "aov", private = TRUE, export = FALSE, envir = getNamespace('stats')) Error in eval(expr, envir, enclos) : cannot add bindings to a locked environment How can make sure the new function is called when S3 method dispatch occurs?