Rev 39360 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
\name{is}\alias{is}\alias{extends}\alias{setIs}\title{Is an Object from a Class}\description{\code{is}:With two arguments, tests whether \code{object} can be treated as from\code{class2}.With one argument, returns all the super-classes of this object's class.\code{extends}:Does the first class extend the second class?Returns \code{maybe} if the extension includes a test.\code{setIs}:Defines \code{class1} to be an extension of \code{class2}.}\usage{is(object, class2)extends(class1, class2, maybe=TRUE, fullInfo = FALSE)setIs(class1, class2, test=NULL, coerce=NULL, replace=NULL,by = character(), where = topenv(parent.frame()), classDef =,extensionObject = NULL, doComplete = TRUE)}\arguments{\item{object}{any \R object.}\item{class1, class2}{the names of the classes between which \code{is} relations are to bedefined.}\item{maybe, fullInfo}{In a call to \code{extends}, \code{maybe} is a flag toinclude/exclude conditional relations, and \code{fullInfo} is aflag, which if \code{TRUE} causes object(s) of class\code{classExtension} to be returned, rather than just thenames of the classes or a logical value. See the detailsbelow.}\item{extensionObject}{ alternative to the \code{test, coerce,replace, by} arguments; an object from class\code{SClassExtension} describing the relation. (Used in internal calls.)}\item{doComplete}{when \code{TRUE}, the class definitions will beaugmented with indirect relations as well. (Used in internal calls.)}\item{test, coerce, replace}{In a call to \code{setIs}, functions optionally supplied to test whether the relation isdefined, to coerce the object to \code{class2}, and to alter theobject so that \code{is(object, class2)} is identical to\code{value}.}\item{by}{In a call to \code{setIs}, the name of an intermediary class. Coercion will proceed by firstcoercing to this class and from there to the target class. (Theintermediate coercions have to be valid.)}\item{where}{In a call to \code{setIs}, where to store the metadata defining the relationship. Default isthe global environment.}\item{classDef}{Optional class definition for \code{class} , required internallywhen \code{setIs} is called during the initial definition of theclass by a call to \code{\link{setClass}}. \emph{Don't} use thisargument, unless you really know why you're doing so.}}\details{\describe{\item{\code{extends}:}{Given two class names, \code{extends} by default says whether thefirst class extends the second; that is, it does for class nameswhat \code{is} does for an object and a class. Given one classname, it returns all the classes that class extends (the\dQuote{superclasses} of that class), including the class itself. Ifthe flag \code{fullInfo} is \code{TRUE}, the result is a list, eachelement of which is an object describing the relationship;otherwise, and by default, the value returned is only the names ofthe classes.}\item{\code{setIs}: }{This function establishes an inheritance relation between twoclasses, by some means other than having one class contain theother. It should \emph{not} be used for ordinary relationships:either include the second class in the \code{contains=} argumentto \code{\link{setClass}} if the class is contained in the usualway, or consider \code{setClassUnion} to define a virtual classthat is extended by several ordinary classes. A call to\code{setIs} makes sense, for example, if one class ought to beautomatically convertible into a second class, but they havedifferent representations, so that the conversion must be done byan explicit computation, not just be inheriting slots, forexample. In this case, you will typically need to provide both a\code{coerce=} and \code{replace=} argument to \code{setIs}.The \code{coerce}, \code{replace}, and \code{by} arguments behave asdescribed for the \code{\link{setAs}} function. It's unlikely youwould use the \code{by} argument directly, but it is used in definingcached information about classes. The value returned (invisibly) by\code{setIs} is the extension information, as a list.The \code{coerce} argument is a function that turns a\code{class1} object into a \code{class2} object. The\code{replace} argument is a function of two arguments that modifies a \code{class1}object (the first argument) to replace the part of it thatcorresponds to \code{class2} (supplied as \code{value}, the secondargument). It then returns the modified object as the value of thecall. In other words, it acts as a replacement method toimplement the expression \code{as(object, class2) <- value}.The easiest way to think of the \code{coerce} and \code{replace}functions is by thinking of the case that \code{class1}contains \code{class2} in the usual sense, by including the slots ofthe second class. (To repeat, in this situation you would not call\code{setIs}, but the analogy shows what happens when you do.)The \code{coerce} function in this case would just make a\code{class2} object by extracting the corresponding slots from the\code{class1} object. The \code{replace} function would replace inthe \code{class1} object the slots corresponding to \code{class2},and return the modified object as its value.The relationship can also be conditional, if a function is supplied as the\code{test} argument. This should be a function of one argumentthat returns \code{TRUE} or \code{FALSE} according to whether theobject supplied satisfies the relation \code{is(object, class2)}.If you worry about such things, conditional relations betweenclasses are slightly deprecated because they cannot be implementedas efficiently as ordinary relations and because they sometimes canlead to confusion (in thinking about what methods are dispatched fora particular function, for example). But they can correspond touseful distinctions, such as when two classes have the same representation,but only one of them obeys certain additional constraints.Because only global environment information is saved, it rarely makessense to give a value other than the default for argument\code{where}. One exception is \code{where=0}, which modifies thecached (i.e., session-scope) information about the class. Classcompletion computations use this version, but don't use it yourselfunless you are quite sure you know what you're doing.}}}\references{The R package \pkg{methods} implements, with a few exceptions, theprogramming interface for classes and methods in the book\emph{Programming with Data} (John M. Chambers, Springer, 1998), inparticular sections 1.6, 2.7, 2.8, and chapters 7 and 8.While the programming interface for the \pkg{methods} package followsthe reference, the R software is an original implementation, sodetails in the reference that reflect the S4 implementation may appeardifferently in R. Also, there are extensions to the programminginterface developed more recently than the reference. For adiscussion of details see \code{?\link{Methods}}and the links from that documentation.}\examples{\dontshow{## A simple class with two slotssetClass("track",representation(x="numeric", y="numeric"))## A class extending the previous, adding one more slot}## a class definition (see \link{setClass} for the example)setClass("trackCurve",representation("track", smooth = "numeric"))## A class similar to "trackCurve", but with different structure## allowing matrices for the "y" and "smooth" slotssetClass("trackMultiCurve",representation(x="numeric", y="matrix", smooth="matrix"),prototype = structure(list(), x=numeric(), y=matrix(0,0,0),smooth= matrix(0,0,0)))## Automatically convert an object from class "trackCurve" into## "trackMultiCurve", by making the y, smooth slots into 1-column matricessetIs("trackCurve","trackMultiCurve",coerce = function(obj) {new("trackMultiCurve",x = obj@x,y = as.matrix(obj@y),curve = as.matrix(obj@smooth))},replace = function(obj, value) {obj@y <- as.matrix(value@y)obj@x <- value@xobj@smooth <- as.matrix(value@smooth)obj})## Automatically convert the other way, but ONLY## if the y data is one variable.setIs("trackMultiCurve","trackCurve",test = function(obj) {ncol(obj@y) == 1},coerce = function(obj) {new("trackCurve",x = slot(obj, "x"),y = as.numeric(obj@y),smooth = as.numeric(obj@smooth))},replace = function(obj, value) {obj@y <- matrix(value@y, ncol=1)obj@x <- value@xobj@smooth <- value@smoothobj})\dontshow{removeClass("trackMultiCurve")removeClass("trackCurve")removeClass("track")}}\keyword{programming}\keyword{classes}\keyword{methods}