[Rd] setClass inside a function
Iago Mosqueira
iago.mosqueira at gmail.com
Tue Apr 24 11:37:46 CEST 2007
Hi Martin,
Thanks very much, your suggestion on the "where" argument did the trick.
Many thanks,
Iago
>
> "Iago Mosqueira (Cefas)" <Iago.Mosqueira at cefas.co.uk> writes:
>
> > Hi Martin,
> >
> > Thanks very much for your help.
> >
> >> Hi Iago --
> >>
> >> Here's my attempt at an answer.
> >>
> >> "Iago Mosqueira (Cefas)" <Iago.Mosqueira at cefas.co.uk> writes:
> >>
> >> > set of S4 classes. But setClass is choking when my function
> >> is called
> >> > isnide a package, telling about an error in
> exists(cname, where). I
> >> > assume this to be a problem with the environment where
> the class is
> >> > created. If I define my creator function in a package
> and load it,
> >> > when I call it I get
> >> >
> >> > Error in assign(mname, def, where): cannot add bindings
> to a locked
> >> > environment
> >>
> >> You're trying to create a class in the package name space, and the
> >> name space is locked (cannot be modified) after the package is
> >> loaded. If your intention is programmatically generate
> static classes
> >> (in a kind of macro-like way) then I think you could still use this
> >> approach but ensure that the classes are created when the
> package is
> >> loaded (e.g., by including a class creation function that
> is actually
> >> evaluated, not just defined, in your package code).
> >
> > Yes, I have tried that. Inmediatly after the creator function is
> > defined I use it to create a new class. And this class is exported
> > in the package NAMESPACE. Still, it says the package environment is
> > locked, although the call to setClass is part of the package.
>
> Try removing the 'where' argument in setClass; or replacing it with
> topenv(parent.frame()) -- the top environment when the package is
> loaded is the name space.
>
> Also, for fun,
>
> >> > # validity
> >> > foo <- "validity <- function(object) {"
> >> > # foo <- c(foo, "browser()")
> >> > foo <- c(foo, paste("if(all(names(dimnames(object)) != c('",
> >> > paste(names(dimnames), collapse="','", sep=""), "')))",
> >> > sep=""))
> >> > foo <- c(foo, "stop(paste('dimnames are not correct for class',
> >> > name))")
> >> > foo <- c(foo, "return(TRUE)}")
> >> > eval(parse(text=foo))
>
> you can write something like
>
> validity <- function (object) {
> msg <- NULL
> cat("checking", name, "/", class(object), "validity\n")
> if (all(names(dimnames(object)) != c("iter", "y")))
> msg <- paste("dimnames are not correct for class", name)
> if (is.null(msg)) TRUE
> else msg
> }
>
> and continue to include validity=validity in setClass. This will use
> R's lexical scope to figure out the correct name, etc for each class
> created. Note also that the idea is that the validity function either
> returns TRUE or a character string, not itself calling 'stop'.
>
> >> > # constructors
> >> > eval(parse(text=paste("setGeneric('", name,
> >> > "', function(object, ...) standardGeneric('",
> >> name, "'))",
> >> > sep="")))
>
> I had expected that
>
> setGeneric(name,
> function(object, ...) standardGeneric(name))
>
> would work, but apparently not. This might be a bit cleaner way to
> create complcated substitutions;
>
> eval(substitute({
> setGeneric(NAME,
> function(object, ...) {
> standardGeneric(NAME)
> })
> }, list(NAME=name)))
>
> >> > setMethod(name, signature(object='missing'),
> >> > function(...) {
> >> > return(FLPar(..., class=name))
> >> > }
> >> > )
>
> It's a bit surprising that this setMethod works, as the function
> signature is different from the generic. This might cause problems
> further down the line. I would have thought that the correct
> formulation would be along the lines of
>
> setMethod(name, signature(object='missing'),
> function(object, ...) {
> FLPar(..., class=name)
> })
>
> Martin
> --
> Martin Morgan
> Bioconductor / Computational Biology
> http://bioconductor.org
>
More information about the R-devel
mailing list