15.3 Details on defining the class
15.3.2 Instantiation
Create an instance of the class at two levels:
- For developer (you):
methods::new()
- For user: constructor function
15.3.3 Validation
S4 objects
- Check class of slot at creation
Person(mtcars)
#> Error in validObject(.Object): invalid class "Person" object: invalid object for slot "name" in class "Person": got class "data.frame", should be or extend class "character"
- Do not check other things
Person("Hadley", age = c(30, 37))
#> An object of class "Person"
#> Slot "name":
#> [1] "Hadley"
#>
#> Slot "age":
#> [1] 30 37
That’s where validation comes in–at two stages:
- At creation
- At modification
15.3.3.1 At creation
setValidity("Person", function(object) {
if (length(object@name) != length(object@age)) {
"@name and @age must be same length"
} else {
TRUE
}
})
#> Class "Person" [in ".GlobalEnv"]
#>
#> Slots:
#>
#> Name: name age
#> Class: character numeric
Person("Hadley", age = c(30, 37))
#> Error in validObject(.Object): invalid class "Person" object: @name and @age must be same length
15.3.3.2 At modification
# get value
setGeneric("name", function(x) standardGeneric("name"))
#> [1] "name"
setMethod("name", "Person", function(x) x@name)
# set value--and assess whether resulting object is valid
setGeneric("name<-", function(x, value) standardGeneric("name<-"))
#> [1] "name<-"
setMethod("name<-", "Person", function(x, value) {
x@name <- value
validObject(x)
x
})
# normal name; no problem
name(john) <- "Jon Smythe"
name(john)
#> [1] "Jon Smythe"
# invalid name; error thrown
name(john) <- letters
#> Error in validObject(x): invalid class "Person" object: @name and @age must be same length