Skip to content

robertzk/super

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fix R namespace collision Build Status Coverage Status

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.

Installation

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")

Another example

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"

About

Giving R the ability to invoke "parent" methods, solving the namespace collision issue

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages