Menu
Coddy logo textTech

Print- und Format-Methoden

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

Wenn ein Wert ausgegeben wird, ruft R die Funktion print() auf. Ohne spezielle Anpassung für die Klasse wird ein S3-Objekt als seine Liste gefolgt vom Klassenattribut ausgegeben, was schwer zu lesen ist:

m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
print(m)

Ausgabe:

$amount
[1] 9.5

$currency
[1] "EUR"

attr(,"class")
[1] "money"

Eine Methode ist eine Funktion namens generic.class. Wenn print() ein Objekt der Klasse money erhält, sucht es nach print.money() und ruft stattdessen diese auf. Eine Print-Methode schreibt mit cat() und endet mit invisible(x), sodass sie das Objekt zurückgibt, ohne es ein zweites Mal auszugeben:

print.money <- function(x, ...) {
  cat("<money ", x$amount, " ", x$currency, ">\n", sep = "")
  invisible(x)
}
m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
print(m)
m

Ausgabe:

<money 9.5 EUR>
<money 9.5 EUR>

format() ist das Generikum, um einen Wert in Text umzuwandeln. Eine Methode format.money() gibt den Text zurück, statt ihn auszugeben, sodass anderer Code ihn in einen Satz einsetzen kann und die Print-Methode ihn wiederverwenden kann:

format.money <- function(x, ...) {
  sprintf("%.2f %s", x$amount, x$currency)
}
print.money <- function(x, ...) {
  cat("Money:", format(x), "\n")
  invisible(x)
}
m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
m
cat("You owe", format(m), "\n")

Ausgabe:

Money: 9.50 EUR 
You owe 9.50 EUR 

Eine Methode nimmt dieselben Argumente wie ihre generische Funktion. print() und format() sind als function(x, ...) deklariert, daher beginnen ihre Methoden ebenfalls mit x, .... Das ... akzeptiert zusätzliche Argumente wie digits, die ein Aufrufer übergeben kann. Methoden funktionieren überall dort, wo die generische Funktion aufgerufen wird, zum Beispiel innerhalb von vapply():

format.money <- function(x, ...) sprintf("%.2f %s", x$amount, x$currency)
wallet <- list(
  structure(list(amount = 3, currency = "EUR"), class = "money"),
  structure(list(amount = 0.5, currency = "USD"), class = "money")
)
print(vapply(wallet, format, character(1)))

Ausgabe:

[1] "3.00 EUR" "0.50 USD"
challenge icon

Aufgabe

Einfach

new_money() in Money.R ist vorgegeben. Füge derselben Datei zwei Methoden hinzu:

  • format.money(x, ...) gibt den Betrag mit zwei Dezimalstellen und der Währung zurück: 9.50 EUR.
  • print.money(x, ...) gibt <money 9.50 EUR> in einer eigenen Zeile aus, verwendet format() und gibt invisible(x) zurück.

Der bereitgestellte Code liest Zeilen 9.5 EUR, gibt jedes Geldobjekt aus und gibt anschließend list: mit allen formatierten Beträgen aus, die durch + verbunden sind.

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

Probier es selbst

source("Money.R")

# Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
input <- suppressWarnings(readLines(file("stdin")))
all <- list()
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  m <- new_money(as.numeric(p[1]), p[2])
  print(m)
  all[[length(all) + 1]] <- m
}
cat("list: ", paste(vapply(all, format, character(1)), collapse = " + "), "\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