Menu
Coddy logo textTech

デフォルトメソッド

CoddyのRジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 8/57。

クラスに一致するメソッドがない場合、UseMethod() は デフォルトメソッドである name.default を探します。これは、ジェネリックが認識しないすべてのクラスに対するフォールバックです。

describe <- function(x) UseMethod("describe")
describe.dog <- function(x) paste("a dog called", x$name)
describe.default <- function(x) "something I do not know"
rex <- structure(list(name = "Rex"), class = "dog")
car <- structure(list(), class = "car")
print(describe(rex))
print(describe(car))

出力:

[1] "a dog called Rex"
[1] "something I do not know"

デフォルトメソッドがない場合、未知のクラスに対してジェネリックを呼び出すとエラーで停止します。

describe <- function(x) UseMethod("describe")
describe.dog <- function(x) paste("a dog called", x$name)
car <- structure(list(), class = "car")
describe(car)

出力:

Error in UseMethod("describe") : 
  no applicable method for 'describe' applied to an object of class "car"
Calls: describe
Execution halted

通常の値もディスパッチされます。クラス属性を持たない数値には 暗黙のクラス numeric があり、テキストには character があり、TRUE には logical があるため、これらの名前のメソッドは通常のベクトルに対して機能します:

describe <- function(x) UseMethod("describe")
describe.numeric <- function(x) paste("numbers adding up to", sum(x))
describe.character <- function(x) paste("words:", paste(x, collapse = " "))
describe.default <- function(x) "something else"
print(describe(c(1, 2, 3)))
print(describe(c("a", "b")))
print(describe(TRUE))

出力:

[1] "numbers adding up to 6"
[1] "words: a b"
[1] "something else"

デフォルトメソッドは、丁寧に拒否することもできます。クラス名を示すメッセージとともに stop() を使用すれば、呼び出し側は何が問題だったのかを知ることができます。class(x)[1] はオブジェクトの最初のクラスです。

area <- function(shape) UseMethod("area")
area.square <- function(shape) shape$side^2
area.default <- function(shape) {
  stop("cannot compute the area of a ", class(shape)[1], call. = FALSE)
}
for (s in list(structure(list(side = 2), class = "square"), structure(list(), class = "blob"))) {
  cat(tryCatch(area(s), error = function(e) conditionMessage(e)), "\n")
}

出力:

4 
cannot compute the area of a blob 
challenge icon

チャレンジ

簡単

プレーンなベクトルに対する汎用の describe(x) とそのメソッドを Describe.R に完成させてください:

  • describe.numeric() は 3 numbers, sum 6 を返します。
  • describe.character() は 2 words, longest: apple を返します(最長の単語が同じ長さの場合は、最初の単語を返します)。
  • describe.logical() は 2 of 3 are TRUE を返します。
  • describe.default() は something else を返します。

提供されたコードは、行 num 1,2,3、chr apple,kiwi、lgl TRUE,FALSE,TRUE、または値を持つその他の単語を読み取り、それをリストに変換します。各行に対して describe() を出力します。

コードは Describe.R に記述します。main.R には提供された入力/出力コードが含まれており、編集できません。

自分で試してみよう

source("Describe.R")

# 提供された入出力コード: そのままにしておく
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  values <- strsplit(p[2], ",")[[1]]
  x <- switch(p[1],
    num = as.numeric(values),
    chr = values,
    lgl = as.logical(values),
    list(values))
  cat(describe(x), "\n", sep = "")
}
quiz icon腕試し

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

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

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