Menu
Coddy logo textTech

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"
challenge icon

チャレンジ

簡単

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 = "")
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rオンラインコンパイラ