
R version 2.4.0 alpha (2006-09-17 r39367)
Copyright (C) 2006 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> ##--- S4 Methods (and Classes)
> library(methods)
> ##too fragile: showMethods(where = "package:methods")
> 
> ##-- S4 classes with S3 slots [moved from ./reg-tests-1.R]
> setClass("test1", representation(date="POSIXct"))
[1] "test1"
> x <- new("test1", date=as.POSIXct("2003-10-09"))
> stopifnot(format(x @ date) == "2003-10-09")
> ## line 2 failed in 1.8.0 because of an extraneous space in "%in%"
> 
> stopifnot(all.equal(3:3, 3.), all.equal(1., 1:1))
> 
> ## trace (requiring methods):
> f <- function(x, y) { c(x,y)}
> xy <- 0
> trace(f, quote(x <- c(1, x)), exit = quote(xy <<- x), print = FALSE)
[1] "f"
> fxy <- f(2,3)
> stopifnot(identical(fxy, c(1,2,3)))
> stopifnot(identical(xy, c(1,2)))
> untrace(f)
> 
> ## a generic and its methods
> 
> setGeneric("f")
[1] "f"
> setMethod("f", c("character", "character"), function(x,	 y) paste(x,y))
[1] "f"
> 
> ## trace the generic
> trace("f", quote(x <- c("A", x)), exit = quote(xy <<- c(x, "Z")), print = FALSE)
[1] "f"
> 
> ## should work for any method
> 
> stopifnot(identical(f(4,5), c("A",4,5)),
+           identical(xy, c("A", 4, "Z")))
> 
> stopifnot(identical(f("B", "C"), paste(c("A","B"), "C")),
+           identical(xy, c("A", "B", "Z")))
> 
> ## trace a method
> trace("f", sig = c("character", "character"), quote(x <- c(x, "D")),
+       exit = quote(xy <<- xyy <<- c(x, "W")), print = FALSE)
[1] "f"
> 
> stopifnot(identical(f("B", "C"), paste(c("A","B","D"), "C")))
> # These two got broken by Luke's lexical scoping fix
> #stopifnot(identical(xy, c("A", "B", "D", "W")))
> #stopifnot(identical(xy, xyy))
> 
> ## but the default method is unchanged
> stopifnot(identical(f(4,5), c("A",4,5)),
+           identical(xy, c("A", 4, "Z")))
> 
> removeGeneric("f")
[1] TRUE
> ## end of moved from trace.Rd
> 
> 
> ## print/show dispatch  [moved from  ./reg-tests-2.R ]
> ## The results  have waffled back and forth.
> ## Currently (R 2.4.0) the intent is that automatic printing of S4
> ## objects should correspond to a call to show(), as per the green
> ## book, p. 332.  Therefore, the show() method is called, once defined,
> ## for auto-printing foo, regardless of the S3 or S4 print() method.
> setClass("bar", representation(a="numeric"))
[1] "bar"
> foo <- new("bar", a=pi)
> foo
An object of class "bar"
Slot "a":
[1] 3.141593

> show(foo)
An object of class "bar"
Slot "a":
[1] 3.141593

> print(foo)
An object of class "bar"
Slot "a":
[1] 3.141593

> 
> setMethod("show", "bar", function(object){cat("show method\n")})
[1] "show"
> show(foo)
show method
> foo
show method
> print(foo)
show method
> # suppressed because output depends on current choice of S4 type or
> # not.  Can reinstate when S4 type is obligatory
> # print(foo, digits = 4)
> 
> print.bar <- function(x, ...) cat("print method\n")
> foo
show method
> print(foo)
print method
> show(foo)
show method
> 
> setMethod("print", "bar", function(x, ...){cat("S4 print method\n")})
Creating a new generic function for "print" in ".GlobalEnv"
[1] "print"
> foo
show method
> print(foo)
S4 print method
> show(foo)
show method
> ## calling print() with more than one argument suppresses the show()
> ## method, largely to prevent an infinite loop if there is in fact no
> ## show() method for this class.  A better solution would be desirable.
> print(foo, digits = 4)
S4 print method
> 
> setClassUnion("integer or NULL", members = c("integer","NULL"))
[1] "integer or NULL"
> setClass("c1", representation(x = "integer", code = "integer or NULL"))
[1] "c1"
> nc <- new("c1", x = 1:2)
> str(nc)# gave ^ANULL^A in 2.0.0
Formal class 'c1' [package ".GlobalEnv"] with 2 slots
  ..@ x   : int [1:2] 1 2
  ..@ code: NULL
> ##
> 
> 
> library(stats4)
> ## the following showMethods() output tends to generate errors in the tests
> ## whenever the contents of the packages change. Searching in the
> ## diff's can easily mask real problems.  If there is a point
> ## to the printout, e.g., to verify that certain methods exist,
> ## hasMethod() would be a useful replacement
> 
> ## showMethods(where = "package:stats4")
> ## showMethods("show")
> ## showMethods("show")
> ## showMethods("plot") # (ANY,ANY) and (profile.mle, missing)
> ## showMethods(classes="mle")
> ## showMethods(classes="matrix")
> ## showMethods(classes=c("matrix", "numeric"))
> ## showMethods(where = "package:methods")
> 
> ## stopifnot(require(Matrix),
> ##           require(lme4)) # -> S4  plot
> ## showMethods("plot") # more than last time
> ## showMethods("show", classes = c("dgeMatrix","Matrix","matrix"))
> ## showMethods("show")
> ## showMethods(classes = c("dgeMatrix","matrix"))
> 
> ##--- "[" fiasco before R 2.2.0 :
> d2 <- data.frame(b= I(matrix(1:6,3,2)))
> ## all is well:
> d2[2,]
     [,1] [,2]
[1,]    2    5
> stopifnot(identical(d2[-1,], d2[2:3,]))
> ## Now make "[" into S4 generic by defining a trivial method
> setClass("Mat", representation(Dim = "integer", "VIRTUAL"))
[1] "Mat"
> setMethod("[", signature(x = "Mat",
+ 			 i = "missing", j = "missing", drop = "ANY"),
+ 	  function (x, i, j, drop) x)
[1] "["
> ## Can even remove the method: it doesn't help
> removeMethod("[", signature(x = "Mat",
+                             i = "missing", j = "missing", drop = "ANY"))
[1] TRUE
> d2[1:2,] ## used to fail badly; now okay
     [,1] [,2]
[1,]    1    4
[2,]    2    5
> stopifnot(identical(d2[-1,], d2[2:3,]))
> ## failed in R <= 2.1.x
> 
> 
> ## Fritz' S4 "odditiy"
> setClass("X", representation(bar="numeric"))
[1] "X"
> setClass("Y", contains="X")
[1] "Y"
> ## Now we define a generic foo() and two different methods for "X" and
> ## "Y" objects for arg missing:
> setGeneric("foo", function(object, arg) standardGeneric("foo"))
[1] "foo"
> setMethod("foo", signature(object= "X", arg="missing"),
+           function(object, arg) cat("an X object with bar =", object@bar, "\n"))
[1] "foo"
> setMethod("foo", signature(object= "Y", arg="missing"),
+           function(object, arg) cat("a Y object with bar =", object@bar, "\n"))
[1] "foo"
> ## Finally we create a method where arg is "logical" only for class
> ## "X", hence class "Y" should inherit that:
> setMethod("foo", signature(object= "X", arg= "logical"),
+           function(object, arg) cat("Hello World!\n") )
[1] "foo"
> ## now create objects and call methods:
> y <- new("Y", bar=2)
> ## showMethods("foo")
> foo(y)
a Y object with bar = 2 
> foo(y, arg=TRUE)## Hello World!
Hello World!
> ## OK, inheritance worked, and we have
> ## showMethods("foo")
> foo(y)
a Y object with bar = 2 
> ## still 'Y' -- was 'X object' in R < 2.3
> 
> 
> ## Multiple inheritance
> setClass("A", representation(x = "numeric"))
[1] "A"
> setClass("B", representation(y = "character"))
[1] "B"
> setClass("C", contains = c("A", "B"), representation(z = "logical"))
[1] "C"
> new("C")
An object of class "C"
Slot "z":
logical(0)

Slot "x":
numeric(0)

Slot "y":
character(0)

> setClass("C", contains = c("A", "B"), representation(z = "logical"),
+          prototype = prototype(x = 1.5, y = "test", z = TRUE))
[1] "C"
> (cc <- new("C"))
An object of class "C"
Slot "z":
[1] TRUE

Slot "x":
[1] 1.5

Slot "y":
[1] "test"

> ## failed reconcilePropertiesAndPrototype(..) after svn r37018
> 
