Menu
Coddy logo textTech

검증기와 도우미

Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 5번째.

생성자는 타입을 확인하고, 검증기는 값을 확인합니다. 관례상 validate_money()는 객체를 받아 각 규칙을 위반할 때마다 명확한 메시지와 함께 stop()을 호출하며, 모든 것이 올바르면 객체를 반환합니다. call. = FALSE는 함수 호출이 메시지에 포함되지 않도록 합니다:

new_money <- function(amount = double(), currency = character()) {
  stopifnot(is.double(amount), is.character(currency))
  structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
  if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
  if (nchar(x$currency) != 3) stop("currency must have 3 letters", call. = FALSE)
  x
}
m <- validate_money(new_money(-5, "EUR"))

출력:

Error: amount must not be negative
Execution halted

helper는 다른 코드가 호출하는 함수입니다. 클래스 이름을 따서 이름이 지정되며, 입력을 올바른 형식으로 변환하고 기본값을 채운 다음 결과를 생성자와 유효성 검사기에 전달합니다:

new_money <- function(amount = double(), currency = character()) {
  stopifnot(is.double(amount), is.character(currency))
  structure(list(amount = amount, currency = currency), class = "money")
}
validate_money <- function(x) {
  if (x$amount < 0) stop("amount must not be negative", call. = FALSE)
  x
}
money <- function(amount, currency = "EUR") {
  validate_money(new_money(as.double(amount), toupper(currency)))
}
m <- money("12", "usd")
cat(m$amount, m$currency)

출력:

12 USD

사용자 입력을 읽는 코드는 tryCatch()를 사용해 검증기의 오류를 포착하고, stop()에 전달된 텍스트인 conditionMessage(e)를 표시합니다:

validate_age <- function(x) {
  if (x$years < 0) stop("age must not be negative", call. = FALSE)
  if (x$years > 150) stop("age is too large", call. = FALSE)
  x
}
age <- function(years) validate_age(structure(list(years = as.double(years)), class = "age"))
for (input in c("30", "-2", "200")) {
  result <- tryCatch(paste("ok", age(input)$years), error = function(e) conditionMessage(e))
  cat(result, "\n")
}

출력:

ok 30 
age must not be negative 
age is too large 

세 함수는 각각 하나의 역할을 담당합니다. new_money()는 엄격하고 빠르며, 이미 올바른 타입을 사용하는 코드에 적합합니다. validate_money()에는 값에 관한 규칙이 들어 있으며, 규칙이 느리게 처리되거나 많을 수 있습니다. money()는 친숙한 함수로, 프로그램의 나머지 부분에서 사용합니다:

new_money()       # 타입만; structure()로 객체를 빌드합니다
validate_money()  # 값 규칙; 메시지와 함께 stop(), 아니면 x 반환
money()           # 입력을 변환한 다음 validate_money(new_money(...))
challenge icon

챌린지

쉬움

new_score(points, max)는 Score.R에서 score 객체를 생성합니다. 같은 파일의 나머지 함수들을 완성하세요:

  • validate_score(x)는 points must not be negative, max must be positive 또는 points must not exceed max와 함께 중지하며, 이 순서대로 검사하고, 그렇지 않으면 x를 반환합니다.
  • score(points, max = 100)는 as.double()를 사용하여 두 인수를 모두 변환하고 validate_score(new_score(...))를 반환합니다.
  • format.score(x, ...)는 45/50 (90%)을 반환하며, 백분율은 정수로 반올림합니다.

모든 stop()에서 call. = FALSE를 사용하세요. 제공된 코드는 45 50 줄을 읽고, 형식이 지정된 점수를 출력하거나 error: 와 메시지를 출력합니다.

코드는 Score.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.

직접 해보기

source("Score.R")

# 제공된 입력/출력 코드: 그대로 유지하세요
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  s <- tryCatch(score(p[1], p[2]), error = function(e) conditionMessage(e))
  if (is.character(s)) cat("error: ", s, "\n", sep = "") else cat(format(s), "\n", sep = "")
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 R 컴파일러