From Iago.Mosqueira at cefas.co.uk  Fri Apr 20 18:31:51 2007
From: Iago.Mosqueira at cefas.co.uk (Iago Mosqueira (Cefas))
Date: Fri, 20 Apr 2007 17:31:51 +0100
Subject: [Rd] setClass inside a function
In-Reply-To: <6phirbr81bi.fsf@gopher4.fhcrc.org>
Message-ID: <40A15E1D8A76A949AF0271EF3133E1A9CF7E6B@LOWEXPRESS.corp.cefas.co.uk>

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:
> 
> > 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). 

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.

> > 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.

Thanks very for this clarification.

> Hope that helps, and is not too misleading.

Not all, very helpful. Cheers,

Iago


> 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
> > re...{{dropped}}
> >
> > ______________________________________________ R-devel at r-project.org
> > mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> -- 
> Martin Morgan
> Bioconductor / Computational Biology
> http://bioconductor.org
> 


***********************************************************************************
This email and any attachments are intended for the named re...{{dropped}}



[Rd] setClass inside a function
Iago Mosqueira (Cefas