printとformatメソッド
CoddyのRジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 4/57。
値が出力されるとき、R は関数 print() を呼び出します。クラスに特別な処理を指定しない場合、S3 オブジェクトはクラス属性に続けてリストとして出力されるため、読みにくくなります。
m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
print(m)出力:
$amount
[1] 9.5
$currency
[1] "EUR"
attr(,"class")
[1] "money"メソッドとは、generic.classという名前の関数です。print()がクラスmoneyのオブジェクトを受け取ると、print.money()を探して、代わりにそれを呼び出します。printメソッドはcat()で書き込み、invisible(x)で終了するため、オブジェクトをもう一度出力せずに返します:
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出力:
<money 9.5 EUR>
<money 9.5 EUR>format()は値をテキストに変換するための汎用メソッドです。format.money()メソッドはテキストを出力する代わりに返すため、他のコードで文の一部として使用でき、printメソッドでも再利用できます。
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")出力:
Money: 9.50 EUR
You owe 9.50 EUR メソッドは、そのジェネリックと同じ引数を受け取ります。print() と format() は function(x, ...) として宣言されているため、それらのメソッドも x, ... で始まります。... は、呼び出し側が渡す可能性のある digits などの追加の引数を受け取ります。メソッドは、ジェネリックが呼び出される場所ならどこでも機能します。たとえば、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)))出力:
[1] "3.00 EUR" "0.50 USD"チャレンジ
簡単Money.R にある new_money() が与えられています。同じファイルに2つのメソッドを追加してください:
format.money(x, ...)は、金額を小数点以下2桁で表示し、通貨を付けて返します:9.50 EUR。print.money(x, ...)は、format()を使用して、独立した行に<money 9.50 EUR>を出力し、invisible(x)を返します。
提供されたコードは 9.5 EUR の行を読み込み、すべての money オブジェクトを出力した後、フォーマット済みのすべての金額を + で結合して list: とともに出力します。
コードは Money.R に記述してください。main.R には提供された入出力コードが含まれており、編集できません。
自分で試してみよう
source("Money.R")
# 提供された入出力コード: そのままにしておく
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 = "")
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Rオンラインコンパイラ