Menu
Coddy logo textTech

妥当性チェック

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

型は R によってチェックされます。値に関するルールはあなたが定義します。setClass() の validity 引数は、object を受け取り、オブジェクトが問題なければ TRUE を、問題の内容を説明する文字列を返す関数です。new() はすべてのオブジェクトに対してこの関数を実行します。

setClass("Account", slots = c(owner = "character", balance = "numeric"),
  validity = function(object) {
    if (object@balance < 0) return("balance must not be negative")
    TRUE
  })
ok <- new("Account", owner = "Ada", balance = 10)
msg <- tryCatch(new("Account", owner = "Bo", balance = -5), error = function(e) conditionMessage(e))
cat(msg)

出力:

invalid class “Account” object: balance must not be negative

妥当性関数は、文字ベクトルを返すことで複数の問題を一度に報告できます。R はエラーメッセージ内でそれらに番号を付けます。

setClass("Range", slots = c(lo = "numeric", hi = "numeric"),
  validity = function(object) {
    problems <- character(0)
    if (length(object@lo) != 1) problems <- c(problems, "lo must be one number")
    if (length(object@hi) != 1) problems <- c(problems, "hi must be one number")
    if (length(problems) == 0) TRUE else problems
  })
msg <- tryCatch(new("Range", lo = c(1, 2), hi = numeric(0)), error = function(e) conditionMessage(e))
cat(msg)

出力:

invalid class “Range” object: 1: lo must be one number
invalid class “Range” object: 2: hi must be one number

@<- は型をチェックしますが妥当性関数は実行しないため、代入によってルールに違反する可能性があります。validObject() はチェックを再度実行します。スロットを変更した後に呼び出してください。

setClass("Account", slots = c(balance = "numeric"),
  validity = function(object) if (object@balance < 0) "balance must not be negative" else TRUE)
a <- new("Account", balance = 10)
a@balance <- -99
cat("still created:", a@balance, "\n")
msg <- tryCatch(validObject(a), error = function(e) conditionMessage(e))
cat(msg, "\n")

出力:

still created: -99 
invalid class “Account” object: balance must not be negative 

R はテキストの前に invalid class “Account” object: を付けます。ユーザーにメッセージを表示するコードでは、object: の後の部分だけを残せます:

setClass("Account", slots = c(balance = "numeric"),
  validity = function(object) if (object@balance < 0) "balance must not be negative" else TRUE)
msg <- tryCatch(new("Account", balance = -1), error = function(e) conditionMessage(e))
cat(sub(".*object: ", "", msg))

出力:

balance must not be negative
challenge icon

チャレンジ

簡単

Rating クラスを Rating.R で宣言し、stars(numeric)と comment(character)のスロット、および最初に該当したルールを返す妥当性検証関数を定義してください。

  • stars が 1、2、3、4、5 のいずれでもない場合は stars must be a whole number from 1 to 5。
  • comment が 20 文字を超える場合は comment is too long。

それ以外の場合は TRUE を返します。提供されたコードは 4;Great のような行を読み込みます(コメントは省略される場合があります)。各評価を作成し、ok: 4/5 または問題のテキストを出力します。

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

自分で試してみよう

source("Rating.R")

# 提供された入出力コード: そのままにしておく
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, ";")[[1]]
  out <- tryCatch({
    r <- new("Rating", stars = as.numeric(p[1]), comment = if (length(p) > 1) p[2] else "")
    paste0("ok: ", r@stars, "/5")
  }, error = function(e) sub(".*object: ", "", conditionMessage(e)))
  cat(out, "\n", sep = "")
}
quiz icon腕試し

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

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

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