The R Project SVN R

Rev

Rev 84105 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8504 maechler 1
#### Testing  UseMethod() and even more NextMethod()
83997 luke 2
#### --------------------
50986 maechler 3
#### i.e.,  S3 methods *only*. For S4, see  reg-S4.R
4
##                                          ~~~~~~~~
8504 maechler 5
 
6
###-- Group methods
7
 
40086 ripley 8
## previous versions used print() and hit an auto-printing bug.
9
 
8504 maechler 10
### Arithmetic "Ops" :
40086 ripley 11
">.bar" <- function(...) {cat("using >.bar\n"); FALSE}
12
">.foo" <- function(...) {cat("using >.foo\n"); TRUE}
8504 maechler 13
Ops.foo <- function(...) {
40086 ripley 14
    cat("using Ops.foo\n")
8504 maechler 15
    NextMethod()
16
}
40086 ripley 17
Ops.bar <- function(...) {
18
    cat("using Ops.bar\n")
19
    TRUE
20
}
8504 maechler 21
 
22
x <- 2:4 ; class(x) <- c("foo", "bar")
23
y <- 4:2 ; class(y) <- c("bar", "foo")
24
 
25
## The next 4 give a warning each about incompatible methods:
26
x > y
27
y < x # should be the same (warning msg not, however)
28
x == y
29
x <= y
30
 
31
x > 3 ##[1] ">.foo"
32
 
33
rm(list=">.foo")
34
x > 3 #-> "Ops.foo" and ">.bar"
35
 
36
 
37
 
38
### ------------  was ./mode-methods.R till R ver. 1.0.x ----------------
39
 
40
###-- Using Method Dispatch on "mode" etc :
22734 jmc 41
## Tests S3 dispatch with the class attr forced to be data.class
42
## Not very relevant when S4 methods are around, but kept for historical interest
8504 maechler 43
abc <- function(x, ...) {
24536 ripley 44
    cat("abc: Before dispatching; x has class `", class(x), "':", sep="")
45
    str(x)
24517 ripley 46
    UseMethod("abc", x) ## UseMethod("abc") (as in S) fails
8504 maechler 47
}
48
 
49
abc.default <- function(x, ...) sys.call()
50
 
51
"abc.(" <- function(x)
52
    cat("'(' method of abc:", deparse(sys.call(sys.parent())),"\n")
53
abc.expression <- function(x)
54
    cat("'expression' method of abc:", deparse(sys.call(sys.parent())),"\n")
55
 
56
abc(1)
57
e0 <- expression((x))
58
e1 <- expression(sin(x))
59
abc(e0)
60
abc(e1)
61
abc(e0[[1]])
62
abc(e1[[1]])
83997 luke 63
 
64
 
84105 luke 65
## Some tests for `nameOfClass()`, called from inherits()
66
ClassX <- structure(list(), name = "ClassX",
67
                    class = c("S3pp_class", "S3pp_object"))
68
 
69
classx_instance <- structure(list(), class = c("ClassX", "S3pp_object"))
70
 
71
nameOfClass.S3pp_class <- function(x) attr(x, "name", TRUE)
72
nameOfClass.foo <- function(x) "bar"
73
 
74
stopifnot(exprs = {
75
    inherits(classx_instance, "ClassX")
76
    inherits(classx_instance, ClassX)
77
    ## ignore class on a character object
78
    isTRUE(inherits(1, structure("numeric", class = "foo")))
79
    ## make sure class is nor evaluated in calling nameOfClass
80
    isFALSE(inherits(1, structure(quote(stop("should not be evaluated")),
81
                                  class = "foo")))
82
})
83
 
84
 
83997 luke 85
## Some tests for `@` dispatching
86
## make sure that
87
## - `@` evals the first args only once,
88
## -  doesn't dispatch for S4
89
## -  works on `.Data` even for nonS4 objects
90
 
91
x <- structure(list(), class = "foo", prop1 = 'prop1val')
92
registerS3method("@", "foo",
93
    function(x, name) {
94
        stopifnot(typeof(name) == "character", length(name) == 1L)
95
        cat(sprintf("called `@.foo`(x = %s, name = '%s')\n",
96
                     deparse1(substitute(x), "\n"), name))
97
        attr(x, name, TRUE)
98
    }
99
)
100
x@prop1
101
 
102
abc <- x
103
abc@prop1
104
 
105
{
106
    cat("new x\n")
107
    structure(list(), class = "foo", prop1 = 'prop1val')
108
}@prop1
109
 
110
makeActiveBinding("ax", function(x) {
111
    cat("evaluating ax\n")
112
    get("x", envir = parent.frame())
113
}, environment())
114
 
115
ax@prop1
116
 
117
stopifnot(exprs = {
118
    identical( x@prop1, "prop1val")
119
    identical(ax@prop1, "prop1val")
120
 
121
    identical(letters@.Data, letters)
122
})
123
 
124
try(letters@foo) # error
125
 
126
# doesn't dispatch for S4
127
setClass("Person",
128
  slots = c(
129
    name = "character",
130
    age = "numeric"
131
  )
132
)
133
 
134
`@.Person` <- function(x, name) {
135
  stop("called @.Person()\n")
136
}
137
 
138
p <- new("Person", name = "Who", age = -1)
139
stopifnot(p@name == "Who")
84107 luke 140
 
141
 
142
## Some tests for `chooseOpsMethod()`, called from C DispatchGroup() when
143
## 2 methods are found
144
foo_obj <- structure(1, class = "foo")
145
bar_obj <- structure(1, class = "bar")
146
 
147
`+.foo` <- function(e1, e2) "foo"
148
`+.bar` <- function(e1, e2) "bar"
149
 
150
invisible(foo_obj + bar_obj)  # Warning: Incompatible methods
151
 
152
chooseOpsMethod.bar <- function(x, y, mx, my, cl, reverse) TRUE
153
 
154
stopifnot(exprs = {
155
    identical(foo_obj + bar_obj, "bar")
156
    identical(bar_obj + foo_obj, "bar")
157
})