自动重定向功能

时间:2012-02-13 01:59:51

标签: r

语言是R。

我有几个文件:

utilities.non.foo.R
utilities.foo.R
utilities.R

foo是一个拼凑在一起的内部包(用于图像处理,虽然这是无关紧要的)。它工作得很好,但只能在Linux机器上运行,即使在这些机器上尝试编译它也是一件非常大的痛苦。

基本上,utilities.foo.R包含许多需要包foo的函数。 这里的函数称为functionname.foo

我即将开始与没有此软件包或Linux的外部协作者共享此代码,因此我编写了一个文件utilities.non.foo.R,其中包含utilities.foo.R中的所有函数,除了已删除对包foo的依赖。 这些函数都称为functionname.non.foo

对于每个函数,文件utilities.R都有一整堆:

functionname <- function(...) {
    if ( fooIsLoaded() ) {
        functionname.foo(...)
    } else {
        functionname.non.foo(...)
    }
}

我们的想法是只需要加载utilities.R,如果您碰巧拥有包foo(例如我的内部协作者),您将使用该后端。如果您拥有foo(外部协作者),则您将使用非foo后端。

我的问题是:是否有一些方法可以为每个函数名重定向,而无需为每个函数名显式编写上面的代码?

这让我想起(例如)有print方法,print.tableprint.data.frame等,但用户只需要使用print使用的方法是自动选择的。

除了method.class更像method.depends_on_which_package_is_loaded之外,我想要那样做。

有没有办法避免在我的utilities.R文件中为每个函数编写重定向函数?

3 个答案:

答案 0 :(得分:2)

正如Dirk所说,只需使用一个包裹。在这种情况下,将所有新的*.non.foo函数放在一个新的包中,该包也称为foo。将此foo分发给您的协作者,而不是您的内部版本。这样你的实用程序代码可以只是

functionname <- function(...) functionname.foo(...)

无需进行任何检查。

答案 1 :(得分:1)

这是一个想法:编写一个将f设置为f.foof.non.foo的函数。它可以在循环中调用,在给定命名空间中的所有函数(或名称以.foo结尾的所有函数)中调用。

dispatch <- function(s) {
 if ( fooIsLoaded() ) {
    f <- get( paste(s, "foo",     sep=".") )
  } else {
    f <- get( paste(s, "non.foo", sep=".") )
  }
  assign( s, f, envir=.GlobalEnv ) # You may want to use a namespace
}
f.foo     <- function() cat("foo\n")
f.non.foo <- function() cat("non-foo\n")
fooIsLoaded <- function() TRUE
dispatch("f")
f()
fooIsLoaded <- function() FALSE
dispatch("f")
f()

更简单的解决方案是提供相同的名称 两个函数,但将它们放在不同的命名空间/包中。

答案 2 :(得分:0)

这听起来非常低效且不优雅,但是怎么样

funify = function(f, g, package="ggplot2") {
 if(paste("package:", package, sep="") %in% search()) f else 
  { message("how do you intend to work without ", package) ; g}
}
  detach(package:ggplot2)
  foo = funify(paste, function(x) letters[x])
  foo(1:10)
  library(ggplot2)
  foo = funify(paste, function(x) letters[x])
  foo(1:10)