Reputation: 238
I want to provide a function called "Sdt" in my package. There are multiple methods of it, but they all lead to Sdt.default(a, b, c, d), which returns a named vector with some calculated stuff for a,b,c and d.
But in some cases the user of my package needs to extend Sdt.default, for example, if he/she wants to try out some other calculations with the four variables.
So I thought: Why not temporarily overwrite the function? So I tried something like this (with Sdt of course, but this is a better toy example):
a <- function() print("FUNCTION A CALLED")
b <- function() print("FUNCTION B CALLED")
c <- function() a()
d <- function(){
a()
a <- b
a()
c()
}
d()
The outcome looks like
[1] "FUNCTION A CALLED"
[1] "FUNCTION B CALLED"
[1] "FUNCTION A CALLED"
But I want to have
[1] "FUNCTION A CALLED"
[1] "FUNCTION B CALLED"
[1] "FUNCTION B CALLED"
The "<<-" operator would work in this example, but if a() is defined within a package it would throw error messages, ("determined function within a package can't be altered" or something like that)
TL;DR How to override from global environment a function within a package temporarily but completly, so all following and nested calls use the altered function?
Upvotes: 2
Views: 1105
Reputation: 57210
You could use assign
function to put your newly created function into the global environment.
Have a look at this example replacing base sum
function :
callSum <- function() sum(1)
main <- function(){
# here we use the original sum function -> we expect 1
print(sum(1))
# let's create a new sum function returning always 100
# and assign it to the global env. with name "sum"
# (note that the name of this function object is not important,
# but the name used in assign is crucial)
newSum <- function(v) {return(100)}
assign("sum", newSum, envir=globalenv())
# let's call sum(1) -> we expect 100
print(sum(1))
# let's call a function that calls sum(1) -> we expect 100
print(callSum())
# we don't want to return anything...
invisible()
}
main()
it prints:
[1] 1
[1] 100
[1] 100
However, this is not really a clean solution.
If you think you need to switch between the package implementation and a custom implementation very often, I suggest to create a wrapper of Std
and use it wherever you want to use the Std
function. In this way, when you want to stop using the package version, you just have to change the wrapper implementation, e.g. :
StdWrapper <- function(a,b,c,d){
return(Std(a,b,c,d))
# return(YourCustomStd(a,b,c,d))
# as soon as you need to switch to a custom implementation,
# just comment the first line and uncomment the second and vice-versa
}
Upvotes: 1
Reputation: 44614
I'm a fan of @DavidArenburg's solution, but if defining default arguments for all of the variables you want to temporarily override isn't an option, this is another way:
d <- function(){
a()
a <- b
a()
environment(c) <- environment()
c()
}
d()
# [1] "FUNCTION A CALLED"
# [1] "FUNCTION B CALLED"
# [1] "FUNCTION B CALLED"
c()
# [1] "FUNCTION A CALLED"
Upvotes: 3
Reputation: 92282
I wouldn't use neither assign
or <<-
. I would just modify c()
function
a <- function() print("FUNCTION A CALLED")
b <- function() print("FUNCTION B CALLED")
c <- function(x = a) x()
d <- function(){
a()
a <- b
a()
c(a)
}
d()
## [1] "FUNCTION A CALLED"
## [1] "FUNCTION B CALLED"
## [1] "FUNCTION B CALLED"
While c()
without a parameter will work the same
c()
## [1] "FUNCTION A CALLED"
Upvotes: 3