Menu
Coddy logo textTech

Slots and Access

Part of the Object Oriented Programming section of Coddy's R journey. Lesson 23 of 57.

obj@slot <- value changes a slot. Like S3 objects, S4 objects are values: a function that changes one works on its own copy and returns it:

setClass("Person", slots = c(name = "character", age = "numeric"))
birthday <- function(p) {
  p@age <- p@age + 1
  p
}
ada <- new("Person", name = "Ada", age = 36)
older <- birthday(ada)
cat(ada@age, older@age)

Output:

36 37

slot(obj, "name") does the same as @ with the slot name in a string, so it works with a name held in a variable. slotNames() lists the slots of a class or object:

setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
for (s in slotNames(ada)) cat(s, "=", format(slot(ada, s)), "\n")
slot(ada, "age") <- 37
print(ada@age)

Output:

name = Ada 
age = 36 
[1] 37

Every assignment is checked against the declared type, not only new(). A wrong value is refused and the object keeps its old one:

setClass("Person", slots = c(name = "character", age = "numeric"))
ada <- new("Person", name = "Ada", age = 36)
ada@age <- "old"

Output:

Error in (function (cl, name, valueClass)  : 
  assignment of an object of class “character” is not valid for @‘age’ in an object of class “Person”; is(value, "numeric") is not TRUE
Execution halted

getSlots() returns every slot name with its declared type, which lets code convert text input to the type a slot expects:

setClass("Person", slots = c(name = "character", age = "numeric"))
types <- getSlots("Person")
print(types)
value <- "40"
if (types[["age"]] == "numeric") value <- as.numeric(value)
print(value + 1)

Output:

       name         age 
"character"   "numeric" 
[1] 41
challenge icon

Challenge

Easy

The class Profile in Profile.R has the slots name and city (character) and age (numeric). Complete two functions:

  • update_profile(p, field, value) stops with no field email (use call. = FALSE) when the field is not a slot; otherwise it converts the text value with as.numeric() when the slot is numeric, sets the slot with slot() and returns the changed profile.
  • profile_lines(p) returns one line per slot, in slot order: name: Ada.

The supplied code reads a name, then lines city=Paris or age=36, applies each, and prints the profile's lines.

Your code goes in Profile.R. main.R holds the supplied input/output code and cannot be edited.

Try it yourself

source("Profile.R")

# Supplied input/output code: keep it as it is
input <- suppressWarnings(readLines(file("stdin")))
p <- new("Profile", name = input[1], city = "unknown", age = 0)
for (line in input[-1]) {
  kv <- strsplit(line, "=")[[1]]
  p <- tryCatch(update_profile(p, kv[1], kv[2]), error = function(e) {
    cat("error: ", conditionMessage(e), "\n", sep = "")
    p
  })
}
for (l in profile_lines(p)) cat(l, "\n", sep = "")
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Online R compiler