class
class
character
class
list
, mais pas d'obligation
r$> p1 <- c(1, 2)
r$> class(p1) <- c("point", "numeric")
r$> p2 <- c(1, 2)
r$> attributes(p2) <- list(class = c("point",
"numeric"))
r$> p3 <- structure(c(3, 4), class = c("point",
"numeric"))
class<-
, attributes<-
ou structure
n'est ni élégant, pratique ou sécuritaire
point <- function(v){
v <- as.numeric(v)
stopifnot(identical(length(v), 2L))
structure(v, class = c("point", class(v)))
}
r$> point(1:3)
Error in point(1:3): identical(length(v), 2L)
is not TRUE
r$> point(letters[1:2])
Warning message in point(letters[1:2]):
“NAs introduced by coercion”
[1] NA NA
attr(,"class")
[1] "point" "numeric"
point(1:2)
[1] 1 2
attr(,"class")
[1] "point" "numeric"
méthode.classe(...)
print
r$> var
\( \Leftrightarrow \) r$> print(var)
print
pour point
norme
retournant la norme euclidienne du vecteur correspondant
print.point <- function(x, ...)
cat("x =", x[1],
"& y =", x[2], "\n")
r$> p1 <- 1:2
x = 1 & y = 2
norme.point <- function(x)
as.numeric(sqrt(crossprod(x)))
r$> norme(point(c(3, 4)))
Error in norme(point(c(3, 4))) : could
not find function "norme"
r$> summary(cars)
speed dist
Min. : 4.0 Min. : 2.00
1st Qu.:12.0 1st Qu.: 26.00
Median :15.0 Median : 36.00
...
r$> summary(lm(dist ~ speed, cars))
Call:
lm(formula = dist ~ speed, data = cars)
Residuals:
Min 1Q Median 3Q Max
-29.069 -9.525 -2.272 9.215 43.201
Coefficients:
Estimate Std. Error t value Pr(> |t|)
...
summary
summary
ne calcule rien, n'affiche rienUseMethod
r$> methods(summary)
[1] summary.aov summary.aovlist*
[3] summary.aspell* summary.check_packages_in_dir*
[5] summary.connection summary.data.frame
[7] summary.Date summary.default
[9] summary.ecdf* summary.factor
[11] summary.glm summary.infl*
[13] summary.lm summary.loess*
[15] summary.manova summary.matrix
[17] summary.mlm* summary.nls*
[19] summary.packageStatus* summary.POSIXct
[21] summary.POSIXlt summary.ppr*
[23] summary.prcomp* summary.princomp*
[25] summary.proc_time summary.srcfile
[27] summary.srcref summary.stepfun
[29] summary.stl* summary.table
[31] summary.tukeysmooth* summary.warnings
v1 <- structure(c(1, 2),
class = c("vec", "numeric"))
r$> summary.vec(v1)
Error in summary.vec(v1) : could not find
function "summary.vec"
r$> summary.numeric(v1)
Error in summary.vec(v1) : could not find
function "summary.numeric"
r$> summary(v1)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.00 1.25 1.50 1.50 1.75 2.00
summary
(la générique) cherchait méthode pour
vec
😟numeric
😟summary
fonctionne quand même...
r$> summary.default(v1)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.00 1.25 1.50 1.50 1.75 2.00
UseMethod
, 2 arguments
generic
: nom de la méthode à appelerobject
: objet utilisé pour le dispatch (premier argument passé à la générique par défaut) 🪄
norme <- function(x, ...)
UseMethod("norme")
r$> norme(point(c(3, 4)))
[1] 5
isaligned.point <- function(...) {
points <- list(...)
isTRUE(length(points) <= 2) && return(TRUE)
fit <- crossprod(
solve(cbind(1, c(points[[1]][1], points[[2]][1]))),
c(points[[1]][2], points[[2]][2]))
for (p in points[-(1:2)]) {
pred <- crossprod(c(1, p[1]), fit)[1]
isTRUE(all.equal(pred, p[2])) || return(FALSE)
}
TRUE
}
r$> isaligned.point(point(1:2),
point(3:4),
point(5:6))
[1] TRUE
r$> isaligned.point(point(1:2),
point(3:4),
point(5:7))
[1] FALSE
isaligned <- function(...)
UseMethod("isaligned")
r$> isaligned(point(1:2),
point(5:6),
point(9:10))
[1] TRUE
r$> isaligned(point(1:2),
point(5:6),
point(9:11))
[1] FALSE
point
: simple spécialisation de numeric
point
pointM <- function(v, mark = NULL) {
stopifnot(is.null(mark) ||
(is.character(mark) &&
identical(length(mark), 1L)))
p <- point(v)
attr(p, "mark") <- mark
structure(p, class = c("pointM", class(p)))
}
r$> p1 <- pointM(1:2, "Premier point")
r$> p2 <- pointM(3:4, "Second point")
r$> p3 <- pointM(5:6, "Troisième point")
r$> p1
x = 1 & y = 2
r$> norme(p2)
[1] 5
r$> isaligned(p1, p2, p3)
[1] TRUE
pointM
mark
mark.pointM <- function(point)
print(attr(point, "mark"))
mark <- function(point)
UseMethod("mark")
r$> mark(p1)
[1] "Premier point"
r$> mark(p1) <- "1er point"
Error in mark(p1) <- "1er point":
could not find function "mark<-"
`mark<-.pointM` <- function(p, v) {
attr(p, "mark") <- v
p
}
`mark<-` <- function(p, v, ...)
UseMethod("mark<-")
r$> mark(p1) <- "1er point"
r$> mark(p1)
[1] "1er point"
Patrick Fournier (Université du Québec à Montréal) MAT8186 Automne 2023