Hi Iago --

Here's my attempt at an answer.

"Iago Mosqueira (Cefas)" <[EMAIL PROTECTED]> writes:

> Hello,
>
> I would like to create a function that gets passed a class name and
> then calls setClass, and a few other functions, inside. I have done
> this in the past with setmethod, creating accessors for all slots in a
> 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). 

> This does not happen if I redefine the creator function in my working
> environment.

yes, here you are creating the class in the global environment, which
is not locked (!).

> I have attached an example of the kind of function below, and I am
> using R 2.5.0.
>
> Where should I look for information on undertanding what might be
> going on here? Why does this way of working succeeds with setMethod
> but not setClass?

I think that setMethod works because the methods package has already
created an environment within the appropriate name space (try 'ls(<pkg
name space>, all=TRUE)' and look at the '.__<etc>' bindings). What
setMethod does is modfies this environment, rather than the
environment of the name space.

Hope that helps, and is not too misleading.

Martin

> The intention here is to provide an easy way for creating extended
> classes that will inherit from a class already defined, instead of
> array as in the example.
>
> Many thanks,
>
>
> Iago
>
>
> defineClass <- function(name, dimnames) {
>       # dim, names[2], dimnames[2]
>       if(names(dimnames)[1] != 'iter')
>               dimnames <- c(list(iter=1), dimnames)
>       dim <- unlist(lapply(dimnames, length))
>
>       # 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))
>
>       # setClass
>       setClass(name, representation('array'),
>       prototype=prototype(array(as.numeric(NA), dim=dim,
> dimnames=dimnames), units='NA'),
>               validity=validity, where=sys.parent(n=-2))
>
>       # setValidity
>       setValidity(name, validity)
>
>       # constructors
>       eval(parse(text=paste("setGeneric('", name,
>               "', function(object, ...) standardGeneric('", name, "'))",
> sep="")))
>
>       setMethod(name, signature(object='ANY'),
>               function(object, ...)
>                       return(FLPar(object, ..., class=name))
>       )
>       setMethod(name, signature(object='missing'),
>               function(...) {
>                       return(FLPar(..., class=name))
>               }
>       )
>
> }
>
> --- Iago Mosqueira Systems Modelling Cefas Pakefield Rd.  Lowestoft
> NR33 0HT U.K.  Tel +44 (0) 1502 558003
>
>
> ***********************************************************************************
> This email and any attachments are intended for the named\...{{dropped}}

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to