If two packages are loaded which contain namespace collisions (i.e., export a function
with the same name), R has no good strategy for providing the ability to call the
overwritten function. This package aims to solve that problem by defining a super
method which tries to find the next appropriate function to call. You should be
familiar with how R looks for functions.
For example, consider the following scenario.
# Exported in some attached package.
source <- function(file, ...) {
cat("Sourcing file ", sQuote(file), "\n")
base::source(file, ...)
}
By explicitly calling base::source
, this package has effectively monopolized its
interception of the source
function: if a newly loaded package were to take
the same approach, the first package's work would be permanently undone. Imagine a
second package were attached with the following overwrite.
source <- function(file, ...) {
if (otherpackage::has_cached(file, ...)) { otherpackage::cache(file, ...) }
else { base::source(file, ...) }
}
Ideally, instead of calling base::source
directly, it would call the next source
function in the attached search path.
To accomplish this, we can instead use super
:
source <- function(file, ...) {
if (otherpackage::has_cached(file, ...)) { otherpackage::cache(file, ...) }
else { super::super(file, ...) }
}
By using super
, base::source
will be selected if no other package has overwritten
source
-- otherwise, the source
exported by the nearest package in the search
path will be selected.
Note: Obviously, the function that super
selects needs to be commutative
with the current function. If the attach order in the search path matters, there is no good
solution as packages in general do not have control over their attachment order. In the
above example, this is already somewhat apparent: if the function which caches the source
call is called first, then "sourcing file" will only be printed once. On the other hand,
if the first package is attached closer to the global environment, then "sourcing file" will
be printed even on cache hits.
This package is in development and is not yet available on CRAN (as of February 28, 2015). To get the latest development build directly from Github, use the following code snippet.
if (!require("devtools")) install.packages("devtools")
devtools::install_github("robertzk/super")
Note that super
merely looks up the parent environment chain of the calling frame.
Thus, we can use it for local functions as well as attached packages.
function1 <- function() {
print("Top-level")
invisible(NULL)
}
local({
function2 <- function() {
function1 <- function() {
print("Mid-level")
super::super()
}
function3 <- function() {
function1 <- function() {
print("Low-level")
super::super()
}
function1()
}
function3()
}
function2()
})
# Will print
# [1] "Low-level"
# [1] "Mid-level"
# [1] "Top-level"
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.