On Fri, Nov 9, 2012 at 9:10 PM, Tom Roche <Tom_Roche at pobox.com>
wrote:>
> How best to implement a decorator pattern in R? What I mean, why I ask:
>
> A group of ncdf4 users is trying to make it easier (notably for ourselves
:-) to write correctly IOAPI-formatted netCDF. Since IOAPI
>
> http://www.baronams.com/products/ioapi/
>
> decorates netCDF, one obvious way to do a package=ioapi is to decorate the
netCDF API from package=ncdf4. E.g., to add a data variable (datavar) with the
additional IOAPI metadata, ioapi::ncvar_add(...) would call
ncdf4::ncvar_add(...), then (e.g.--not complete, strictly for illustration)
You can pretty much do exactly that. There's no reason why your
package can't have:
ncvar_add = function(x,y,datavar){
ncdf4::ncvar_add(x,y,something with datavar, etc etc with the custom
ioapi stuff)
}
ie, your ncvar_add plays with its args and then calls the ncvar_add
in ncdf4. The problems are then:
* If a user loads both packages, then one function will mask the
other - you'll get a warning, and to use the masked one you have to do
packagename::ncvar_add(foo)
* You may now confuse users. Normally with OO systems you could have
some signature that decided which of a method to call, but you are
going to end up having to superclass the ncdf object... maybe...
horrible...
> I've spent most of my codelife in Java, where one can decorate as above
either
>
> * @ compile-time: simple inheritance. Brittle longterm, but gets the job
done for now.
>
> * @ run-time: real Decorator Pattern ? la the Gang of Four. Not much
harder, usually worth the investment, but not "the simplest thing that
could possibly work," either.
>
> But, given my ignorance of the R object models and dependency management,
before I put much scarce time into researching this, I thought I'd ask the
community for suggestions, references, and especially examples for how to do
this in R, especially how to extend one R package with another.
I'm not sure you can 'extend' an R package with another package -
you
certainly cant just define 'package foo extends package bar' in any
way and expect foo::anything to call bar::anything.
The conventional thing for you to do would be to write a new package
that depends on ncdf4, has functions with unique names, and then calls
ncdf4 package functions to do the ncdf4 level things. Anything wrong
with that?
Barry