attr() does fuzzy matchingUseMethod() is fuzzy“Now for some obscure details that need to appear somewhere” —
?UseMethod
NextMethod() depends on what’s loadedS7::convert() generic)@ to access slots, but they do it anywayS7::new_class()#> <Person>
#> @ name: chr "Jon"
#> @ age : num 50
#> [1] TRUE
#> [1] "Person" "S7_object"
#> [1] TRUE
@#> Error: <Person>@age must be <integer> or <double>, not <character>
#> Error: <Person> object properties are invalid:
#> - @name must be <character>, not <integer>
#> - @age must be <integer> or <double>, not <character>
validator argument customizes validation#> Error: <Person> object is invalid:
#> - @name and @age must be the same length
#> Error: <Person> object is invalid:
#> - @name and @age must be the same length
#> Error: <Person> object is invalid:
#> - @name and @age must be the same length
#> <Person>
#> @ name: chr [1:2] "Jon" "Leyla"
#> @ age : num [1:2] 50 49
S7::new_property() defines custom property typesprop_positive <- new_property(
class = class_numeric,
validator = function(value) {
if (any(value <= 0)) "must be positive"
}
)
class_person <- new_class(
"Person",
properties = list(name = class_character, age = prop_positive),
validator = function(self) {
if (length(self@name) != length(self@age)) {
"@name and @age must be the same length"
}
}
)
us <- class_person(name = c("Jon", "Leyla"), age = c(50, -5))#> Error: <Person> object properties are invalid:
#> - @age must be positive
class_circle2 <- new_class(
"Circle",
properties = list(
radius = class_numeric,
area = new_property(
class = class_numeric,
getter = function(self) pi * self@radius^2,
setter = function(self, value) {
if (!length(value)) return(self)
self@radius <- sqrt(value / pi)
self
}
)
)
)
c2 <- class_circle2(radius = 1)
c2@area#> [1] 3.141593
#> [1] 2
#> [1] TRUE
constructor argument customizes object creationS7::new_generic() and S7::new_method()#> <Person>
#> @ name: chr [1:3] "Jon" "Leyla" "Hadley"
#> @ age : num [1:3] 50 49 46
#> <Person>
#> @ name: chr [1:2] "Jon" "Hadley"
#> @ age : num [1:2] 50 46
#> <Geek>
#> @ name: chr [1:2] "Jon" "Hadley"
#> @ age : num [1:2] 50 46
class_any matches any classclass_missing for missing argumentsclass() for S3 classes, S7_class() for S7 class constructor