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챌린지
쉬움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)) }
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Ruby 컴파일러