Menu
Coddy logo textTech

Slots und Zugriff

Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 23 von 57.

obj@slot <- value ändert einen Slot. Wie S3-Objekte sind S4-Objekte Werte: Eine Funktion, die ein Objekt ändert, arbeitet mit ihrer eigenen Kopie und gibt diese zurück:

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)

Ausgabe:

36 37

slot(obj, "name") macht dasselbe wie @ mit dem Slot-Namen als Zeichenkette und funktioniert daher mit einem in einer Variablen gespeicherten Namen. slotNames() listet die Slots einer Klasse oder eines Objekts auf:

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)

Ausgabe:

name = Ada 
age = 36 
[1] 37

Jede Zuweisung wird anhand des deklarierten Typs geprüft, nicht nur new(). Ein falscher Wert wird abgelehnt, und das Objekt behält seinen alten Wert:

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

Ausgabe:

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() gibt jeden Slot-Namen mit seinem deklarierten Typ zurück, sodass Code Texteingaben in den von einem Slot erwarteten Typ umwandeln kann:

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)

Ausgabe:

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

Aufgabe

Einfach

Die Klasse Profile in Profile.R verfügt über die Slots name und city (character) sowie age (numeric). Vervollständige zwei Funktionen:

  • update_profile(p, field, value) bricht mit no field email ab (verwende call. = FALSE), wenn das Feld kein Slot ist; andernfalls wird der Text value mit as.numeric() umgewandelt, wenn der Slot numerisch ist, der Slot mit slot() gesetzt und das geänderte Profil zurückgegeben.
  • profile_lines(p) gibt eine Zeile pro Slot in der Reihenfolge der Slots zurück: name: Ada.

Der bereitgestellte Code liest einen Namen und anschließend Zeilen wie city=Paris oder age=36 ein, wendet jede davon an und gibt die Zeilen des Profils aus.

Dein Code gehört in Profile.R. main.R enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

source("Profile.R")

# Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-R-Compiler