Rev 58549 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/methods/man/is.Rd% Part of the R package, http://www.R-project.org% Copyright 1995-2009 R Core Team% Distributed under GPL 2 or later\name{is}\alias{is}\alias{extends}\alias{setIs}\title{Is an Object from a Class?}\description{Functions to test inheritance relationships between an object and aclass (\code{is}) or between two classes (\code{extends}), and toestablish such relationships (\code{setIs}, an explicit alternativeto the \code{contains=} argument to \code{\link{setClass}}).}\section{Summary of Functions}{\describe{\item{\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.}\item{\code{extends}:}{Does the first class extend the second class?The call returns \code{maybe} if the extension includes a test.When called with one argument, the value is a vector of thesuperclasses of \code{class1}. If argument \code{fullInfo} is\code{TRUE}, the call returns a named list of objects of class\code{\linkS4class{SClassExtension}}; otherwise, just the names ofthe superclasses.}\item{\code{setIs}:}{Defines \code{class1} to be an extension (subclass) of\code{class2}.If \code{class2} is an existing virtual class, such as a classunion, then only the two classes need to be supplied in thecall, if the implied inherited methods work for \code{class1}.See the details section below.Alternatively, arguments \code{coerce} and \code{replace} shouldbe supplied, defining methods to coerce to the superclass and toreplace the part corresponding to the superclass. As discussed inthe details and other sections below, this form is often lessrecommended than the corresponding call to \code{\link{setAs}}, towhich it is an alternative.Argument \code{test} allows conditional inheritance, in whichthe \code{is()} result is tested for each object rather thanbeing determined by the class definition. This form isdiscouraged when it can be avoided; in particular, note thatconditional inheritance is \emph{not} used to select methods fordispatch.}}}\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 beexamined defined, or (more efficiently) the class definitionobjects for the classes.}\item{maybe, fullInfo}{In a call to \code{extends}, \code{maybe} is the value returned ifa relation is conditional. In a call with \code{class2} missing,\code{fullInfo} is a flag, which if \code{TRUE} causes a list ofobjects of class \code{classExtension} to be returned, rather thanjust the names of the classes.}\item{coerce, replace}{In a call to \code{setIs}, functions optionally supplied to coerce the object to\code{class2}, and to alter the object so that \code{is(object, class2)}is identical to \code{value}. See the details section below.}\item{test}{In a call to \code{setIs}, a \emph{conditional} relationship isdefined by supplying this function. Conditional relations arediscouraged and are not included in selecting methods. See the details section below.The remaining arguments are for internal use and/or usually omitted.}\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{by}{In a call to \code{setIs}, the name of an intermediary class.Coercion will proceed by first coercing to this class and from thereto the target class. (The intermediate coercions have to be valid.)}\item{where}{In a call to \code{setIs}, where to store the metadata defining therelationship. Default is the global environment for calls from thetop level of the session or a source file evaluated there. When thecall occurs in the top level of a file in the source of a package,the default will be the namespace or environment of the package.Other uses are tricky and not usually a good idea, unless you reallyknow what you are doing.}\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.}}\section{Details}{Arranging for a class to inherit from another class is a key tool inprogramming. In \R, there are three basic techniques, the first twoproviding what is called \dQuote{simple} inheritance, the preferred form:%%\enumerate{\itemBy the \code{contains=} argument in a call to \code{\link{setClass}}. Thisis and should be the most common mechanism. It arranges that the newclass contains all the structure of the existing class, and inparticular all the slots with the same class specified. Theresulting class extension is defined to be \code{simple}, withimportant implications for method definition (see the section onthis topic below).\itemMaking \code{class1} a subclass of a virtual classeither by a call to \code{\link{setClassUnion}} to make thesubclass a member of a new class union, or by a call to\code{setIs} to add a class to an existing class union or as a newsubclass of an existing virtual class. In either case, theimplication should be that methods defined for the class union orother superclass all work correctly for the subclass. This maydepend on some similarity in the structure of the subclasses orsimply indicate that the superclass methods are defined in termsof generic functions that apply to all the subclasses. Theserelationships are also generally simple.\itemSupplying \code{coerce} and \code{replace} arguments to \code{setAs}.\R allows arbitrary inheritance relationships, using the samemechanism for defining coerce methods by a call to\code{\link{setAs}}. The difference between the two is simplythat \code{\link{setAs}} will require a call to \code{\link{as}}for a conversion to take place, whereas after the call to\code{\link{setIs}}, objects will be automatically converted tothe superclass.The automatic feature is the dangerous part, mainly because itresults in the subclass potentially inheriting methods that donot work. See the section on inheritance below. If the twoclasses involved do not actually inherit a large collection ofmethods, as in the first example below, the danger may berelatively slight.If the superclass inherits methods where the subclass has only adefault or remotely inherited method, problems are more likely.In this case, a generalrecommendation is to use the \code{\link{setAs}} mechanisminstead, unless there is a strong counter reason. Otherwise, be prepared tooverride some of the methods inherited.}With this caution given, the rest of this section describes whathappens when \code{coerce=} and \code{replace=} arguments are suppliedto \code{setIs}.The \code{coerce} and \code{replace} arguments are functions thatdefine how to coerce a \code{class1} object to \code{class2}, andhow to replace the part of the subclass object that corresponds to\code{class2}. The first of these is a function of one argumentwhich should be \code{from}, and the second of two arguments(\code{from}, \code{value}). For details, see the section on coercefunctions below .When \code{by} is specified, the coerce process first coerces tothis class and then to \code{class2}. 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 revised class definition of \code{class1}.}\section{Coerce, replace, and test functions}{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.For additional discussion of these functions, seethe documentation of the\code{\link{setAs}} function. (Unfortunately, argument\code{def} to that function corresponds to argument \code{coerce} here.)The inheritance 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)}.Conditional relations betweenclasses are discouraged in general because they require a per-objectcalculation to determine their validity. They cannot be appliedas efficiently as ordinary relations and tend to make the code thatuses them harder to interpret. \emph{NOTE: conditional inheritanceis not used to dispatch methods.} Methods for conditionalsuperclasses will not be inherited. Instead, a method for thesubclass should be defined that tests the conditional relationship.}\section{Inherited methods}{A method written for a particular signature (classes matched to oneor more formal arguments to the function) naturally assumes that theobjects corresponding to the arguments can be treated as coming fromthe corresponding classes. The objects will have all the slots andavailable methods for the classes.The code that selects and dispatches the methods ensures that thisassumption is correct. If the inheritance was \dQuote{simple}, thatis, defined by one or more uses of the \code{contains=} argument ina call to \code{\link{setClass}}, no extra work is generallyneeded. Classes are inherited from the superclass, with the samedefinition.When inheritance is defined by a general call to\code{setIs}, extra computations are required. This form ofinheritance implies that the subclass does \emph{not} just containthe slots of the superclass, but instead requires the explicit callto the coerce and/or replace method. To ensure correct computation,the inherited method is supplemented by calls to \code{\link{as}}before the body of the method is evaluated.The calls to \code{\link{as}} generated in this case have theargument \code{strict = FALSE}, meaning that extra information canbe left in the converted object, so long as it has all theappropriate slots. (It's this option that allows simple subclassobjects to be used without any change.) When you are writing yourcoerce method, you may want to take advantage of that option.Methods inherited through non-simple extensions can result in ambiguitiesor unexpected selections. If \code{class2} is a specialized classwith just a few applicable methods, creating the inheritancerelation may have little effect on the behavior of \code{class1}.But if \code{class2} is a class with many methods, you mayfind that you now inherit some undesirable methods for\code{class1}, in some cases, fail to inherit expected methods.In the second example below, the non-simple inheritance from class\code{"factor"} might be assumed to inherit S3 methods via thatclass. But the S3 class is ambiguous, and in fact is\code{"character"} rather than \code{"factor"}.For some generic functions, methods inherited by non-simpleextensions are either known to be invalid or sufficiently likely tobe so that the generic function has been defined to exclude suchinheritance. For example \code{\link{initialize}} methods mustreturn an object of the target class; this is straightforward if theextension is simple, because no change is made to the argumentobject, but is essentially impossible. For this reason, the genericfunction insists on only simple extensions for inheritance. See the\code{simpleInheritanceOnly} argument to \code{\link{setGeneric}}for the mechanism. You can use this mechanism when defining newgeneric functions.If you get into problems with functions that do allow non-simpleinheritance, there are two basic choices. Eitherback off from the \code{setIs} call and settle for explicit coercingdefined by a call to \code{\link{setAs}}; or, define explicitmethods involving \code{class1} to override the bad inheritedmethods. The first choice is the safer, when there are seriousproblems.}\seealso{\code{\link{inherits}} is nearly always equivalent to\code{is}, both for S4 and non-S4 objects, and is somewhat faster.The non-equivalence applies to classes that have conditionalsuperclasses, with a non-trivial \code{test=} in the relation (notcommon and discouraged): for these, \code{is} tests for therelation but \code{inherits} by definition ignores conditionalinheritance for S4 objects.\code{\link{selectSuperClasses}(cl)} has similar semantics as\code{extends(cl)}, typically returning subsets of the latter.}\references{Chambers, John M. (2008)\emph{Software for Data Analysis: Programming with R}Springer. (For the R version.)Chambers, John M. (1998)\emph{Programming with Data}Springer (For the original S4 version.)}\examples{\dontshow{## A simple class with two slotssetClass("track",representation(x="numeric", y="numeric"))## A class extending the previous, adding one more slot}## Two examples of setIs() with coerce= and replace= arguments## The first one works fairly well, because neither class has many## inherited methods do be disturbed by the new inheritance## The second example does NOT work well, because the new superclass,## "factor", causes methods to be inherited that should not be.## First example:## a class definition (see \link{setClass} for class "track")setClass("trackCurve", contains = "track",representation( 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),smooth = as.matrix(obj@smooth))},replace = function(obj, value) {obj@y <- as.matrix(value@y)obj@x <- value@xobj@smooth <- as.matrix(value@smooth)obj})\dontshow{removeClass("trackMultiCurve")removeClass("trackCurve")removeClass("track")}## Second Example:## A class that adds a slot to "character"setClass("stringsDated", contains = "character",representation(stamp="POSIXt"))## Convert automatically to a factor by explicit coercesetIs("stringsDated", "factor",coerce = function(from) factor(from@.Data),replace= function(from, value) {from@.Data <- as.character(value); from })\dontshow{set.seed(750)}ll <- sample(letters, 10, replace = TRUE)ld <- new("stringsDated", ll, stamp = Sys.time())levels(as(ld, "factor"))levels(ld) # will be NULL--see comment in section on inheritance above.## In contrast, a class that simply extends "factor"## has no such ambiguitiessetClass("factorDated", contains = "factor",representation(stamp="POSIXt"))fd <- new("factorDated", factor(ll), stamp = Sys.time())identical(levels(fd), levels(as(fd, "factor")))}\keyword{programming}\keyword{classes}\keyword{methods}