Menu
Coddy logo textTech

case와 클래스

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

case는 값의 클래스에 따라 분기할 수 있습니다. when Integer는 모든 정수와 일치합니다. case는 ===와 비교하기 때문이며, Integer === 5는 5가 Integer인지(is_a?) 묻습니다.

def describe(value)
  case value
  when Integer then "integer #{value}"
  when Float then format("float %.2f", value)
  when String then "text of #{value.size} chars"
  when nil then "nothing"
  else "other: #{value.class}"
  end
end

[5, 2.5, "hi", nil, [1, 2]].each { |v| puts describe(v) }

출력:

integer 5
float 2.50
text of 2 chars
nothing
other: Array

클래스에 대한 ===는 is_a?를 따르므로, 슈퍼클래스를 사용하는 when은 그 서브클래스도 일치시킵니다. 분기의 순서를 가장 구체적인 클래스부터 가장 일반적인 클래스 순으로 지정하세요:

class Animal
end

class Dog < Animal
end

def kind(x)
  case x
  when Dog then "a dog"
  when Animal then "some animal"
  else "not an animal"
  end
end

puts kind(Dog.new)
puts kind(Animal.new)
puts kind("Rex")
puts Animal === Dog.new

출력:

a dog
some animal
not an animal
true

하나의 when에 여러 클래스를 나열할 수 있으며, 각 분기에서 값으로 실제 작업을 수행할 수 있습니다. 예를 들어 여러 타입이 섞인 중첩 구조의 합계를 계산할 수 있습니다:

def total(value)
  case value
  when Integer, Float then value
  when String then value.to_f
  when Array then value.sum { |v| total(v) }
  when Hash then total(value.values)
  else 0
  end
end

puts total([1, "2.5", { a: 3, b: [4, nil] }])

출력:

10.5

클래스를 기준으로 분기하는 방식은 숫자, 문자열, 배열처럼 새로운 메서드를 추가할 수 없는 클래스의 값이나 외부에서 들어온 데이터에 적합합니다. 직접 만든 클래스에는 다형성을 우선 사용하세요. 그러면 새 클래스에는 모든 case에 새 분기를 추가하는 대신 새 메서드만 추가하면 됩니다.

# 자신의 클래스: 각각이 답하게 하세요
shape.area

# 외부의 내장 값: 클래스에 따라 분기하세요
case value
when Integer then ...
when String then ...
end
challenge icon

챌린지

쉬움

functions.rb에서 값의 클래스에 대해 case를 사용하도록 도우미 describe(value)를 완성하세요. 이 도우미는 integer 5 (odd) 또는 integer 4 (even), 소수점 두 자리로 표시된 float 2.50, text "hi" (2 chars), list of 3: 1, a, 2.5(요소를 to_s로 변환한 뒤 결합한 결과), nil에 대해 nothing을 반환하고, 그 외 모든 값에 대해 other Symbol을 반환합니다. 테스트에서 사용되는 유일한 다른 종류는 심볼입니다.

제공된 코드는 각 입력 줄을 값(정수, 소수, [a,b] 목록, nil, :name 심볼 또는 텍스트)으로 변환한 다음 각각에 대해 describe를 출력합니다.

여러분의 코드는 functions.rb에 작성합니다. main.rb에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.

직접 해보기

require_relative 'functions'

# 제공된 입력/출력 코드: 그대로 유지하세요
input = []
while (line = gets)
  input << line.chomp
end
def parse(text)
  return Integer(text) if text.match?(/\A-?\d+\z/)
  return Float(text) if text.match?(/\A-?\d+\.\d+\z/)
  return nil if text == "nil"
  return text[1..].to_sym if text.start_with?(":")
  return text[1...-1].split(",").map { |t| parse(t) } if text.start_with?("[")

  text
end

input.each { |line| puts describe(parse(line)) }
quiz icon실력 점검

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

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

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