To test two environments for object equality (Lisp EQ), I can use 'identity':> e1 <- environment(local(function()x)) > e2 <- environment(local(function()x)) > identical(e1,e2) # compares object identity[1] FALSE> identical(as.list(e1),as.list(e2)) # compares values as name->value mapping[1] TRUE # (is there a better way to do this?) What is the corresponding function for testing whether two S4 objects are the same object? It appears that 'identity' for S4 objects compares the *value*, not the *object identity*:> setClass("simple",representation(a="logical"))[1] "simple"> s1 <- new("simple"); s2 <- new("simple") > identical(s1,s1)[1] TRUE # not surprising> identical(s1,s2)[1] TRUE # ? not comparing object identity> s1 at a <- TRUE > s2 at a <- TRUE > identical(s1,s2)[1] TRUE> s1 at a <- TRUE > s2 at a <- FALSE > identical(s1,s2)[1] FALSE Thanks, -s
Hi Stavros -- Stavros Macrakis <macrakis at alum.mit.edu> writes:> To test two environments for object equality (Lisp EQ), I can use 'identity': > >> e1 <- environment(local(function()x)) >> e2 <- environment(local(function()x)) >> identical(e1,e2) # compares object identity > [1] FALSE >> identical(as.list(e1),as.list(e2)) # compares values as name->value mapping > [1] TRUE # (is there a better way to do this?) > > What is the corresponding function for testing whether two S4 objects > are the same object? It appears that 'identity' for S4 objects > compares the *value*, not the *object identity*:Hi Stavros S4 objects do not have the semantics of environments, but of lists (or of most other R objects), so it is as meaningful to ask why identical(s1, s2) returns TRUE as it is to ask why identical(list(x=1), list(x=1)) returns TRUE. Martin>> setClass("simple",representation(a="logical")) > [1] "simple" >> s1 <- new("simple"); s2 <- new("simple") >> identical(s1,s1) > [1] TRUE # not surprising >> identical(s1,s2) > [1] TRUE # ? not comparing object identity >> s1 at a <- TRUE >> s2 at a <- TRUE >> identical(s1,s2) > [1] TRUE >> s1 at a <- TRUE >> s2 at a <- FALSE >> identical(s1,s2) > [1] FALSE > > Thanks, > > -s > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.-- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793
On Thu, Jul 30, 2009 at 12:01 PM, Martin Morgan<mtmorgan at fhcrc.org> wrote:> S4 objects do not have the semantics of environments, but of lists (or of most other R objects), so it is as meaningful to ask why identical(s1, s2) returns TRUE as it is to ask why identical(list(x=1), list(x=1)) returns TRUE.Thanks for the clarification. For some reason, I thought that S4 objects (unlike S3 objects) were objects in the conventional computer science sense, that is, mutable. Compare proto objects, which *are* objects in the usual sense:> proto1 <- proto(expr= {x=23}) > proto2 <- proto1 > proto1$x <- 45 > proto2$x[1] 45 # proto1 and proto2 are the same object> setClass("test",representation(a="logical"))[1] "test"> s41 <- new("test") > s42 <- s41 > s41 at a <- TRUE > s42 at a # s41 and s42 are different objectslogical(0) It would thus perhaps be clearer to speak of S4 "values" rather than S4 "objects". -s
Stavros Macrakis wrote:> On Thu, Jul 30, 2009 at 12:01 PM, Martin Morgan<mtmorgan at fhcrc.org> wrote: >> S4 objects do not have the semantics of environments, but of lists (or of most other R objects), so it is as meaningful to ask why identical(s1, s2) returns TRUE as it is to ask why identical(list(x=1), list(x=1)) returns TRUE. > > Thanks for the clarification. > > For some reason, I thought that S4 objects (unlike S3 objects) were > objects in the conventional computer science sense, that is, mutable.S4 objects are mutable in the sense that one can write replacement methods for them setClass("A", representation=representation(aValue="logical")) setGeneric("aValue<-", function(object, value) standardGeneric("aValue<-")) setReplaceMethod("aValue", "A", function(object, value) { slot(object, "aValue") <- value object }) > a <- b <- new("A", aValue=FALSE) > aValue(a) <- TRUE > a An object of class "A" Slot "aValue": [1] TRUE while preserving copy-on-change > b An object of class "A" Slot "aValue": [1] FALSE Martin> Compare proto objects, which *are* objects in the usual sense: > >> proto1 <- proto(expr= {x=23}) >> proto2 <- proto1 >> proto1$x <- 45 >> proto2$x > [1] 45 # proto1 and proto2 are the same object > >> setClass("test",representation(a="logical")) > [1] "test" >> s41 <- new("test") >> s42 <- s41 >> s41 at a <- TRUE >> s42 at a # s41 and s42 are different objects > logical(0) > > It would thus perhaps be clearer to speak of S4 "values" rather than > S4 "objects". > > -s-- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M1 B861 Phone: (206) 667-2793