From janko.thyson.rstuff at googlemail.com  Wed Aug 24 00:02:37 2011
From: janko.thyson.rstuff at googlemail.com (Janko Thyson)
Date: Wed, 24 Aug 2011 00:02:37 +0200
Subject: [Rd] Implementing a "plugin" paradigm with R methods
Message-ID: <4E54237D.3090809@googlemail.com>

Dear list,

I was wondering how to best implement some sort of a "plugin" paradigm 
using R methods and the dispatcher:
Say we have a function/method ('foo') that does something useful, but 
that should be open for extension in ONE specific area by OTHERS using 
my package. Of course they could go ahead and write a whole new 'foo' 
method including the features they'd like to see, but that's not really 
necessary. Rather, they should be able to just write a new "plugin" 
method for that part of 'foo' that I'd like to open for such plugins.

The way I chose below works, but generates warnings as my method has 
signature arguments that don't correspond to formal classes (which is 
totally fine). Of course I could go ahead and make sure that such 
"dummy" classes exist, but I was wondering if there's a better way.

It'd be great if anyone could let me know how they handle "plugin" 
scenarios based on some sort of method dispatch!

Thanks,
Janko

##### CODE EXAMPLE #####

setGeneric(name="foo", signature=c("src"), function(src, ...) 
standardGeneric("foo"))
setGeneric(name="plugin", signature=c("src", "link", "plugin"),
     function(src, link, plugin, ...) standardGeneric("plugin")
)
setMethod(f="plugin", signature=signature(src="character", link="foo", 
plugin="punct"),
     function(src, link, plugin, ...){
         out <- gsub("[[:punct:]]", "", src)
         return(out)
     }
)
setMethod(f="plugin", signature=signature(src="character", link="foo", 
plugin="digit"),
     function(src, link, plugin, ...){
         out <- gsub("[[:digit:]]", "", src)
         return(out)
     }
)
setMethod(f="foo", signature=signature(src="character"),
     function(src, plugin=NULL, ...){
         if(!is.null(plugin)){
             if(!existsMethod(f="plugin",
                 signature=c(src=class(src), link="foo", plugin=plugin)
             )){
                 stop("Invalid plugin")
             }
             .plugin <- selectMethod(
                 "plugin",
                 signature=c(src=class(src), link="foo", plugin=plugin),
                 useInherited=c(src=TRUE, plugin=FALSE)
             )
             out <- .plugin(src=src)
         } else {
             out <- paste("Hello world: ", src, sep="")
         }
         return(out)
     }
)
foo(src="Teststring:-1234_56/")
foo(src="Teststring:-1234_56/", plugin="punct")
foo(src="Teststring:-1234_56/", plugin="digit")



[Rd] Implementing a "plugin" paradigm with R methods
Janko Thyson