트랙
/
Crystal
Crystal
/
연습 문제
/
성의 만찬
성의 만찬

성의 만찬

학습 연습 문제

소개

Crystal에는 Nil이라는 타입이 있어요. 이 타입은 nil이라는 값 하나만 가질 수 있어요. 값이 없음을 나타내는 데 사용하며, 다른 언어의 null이나 None과 비슷해요.

nil 값은 여러 메서드에서 반환될 수 있어요. 예를 들어 String#[]?는 인덱스가 범위를 벗어나면 nil을 반환해요.

"foo"[10]? # => nil

Crystal에는 널 참조 검사라는 것이 있어요. 이는 모든 타입이 기본적으로 nil을 가질 수 없다는 뜻이에요. 따라서 변수를 Nil 타입으로 명시적으로 선언하지 않으면 그 변수에 nil을 할당할 수 없어요. 결과적으로 컴파일러가 널 참조를 자동으로 검사해요.

거짓으로 평가되는 값

nil 값을 다루는 방법에는 여러 가지가 있어요. nil은 false와 마찬가지로 거짓으로 평가되는 값이에요. 그래서 거짓이나 참으로 평가되는 값이 필요한 곳에서는 nil이 false와 똑같이 취급돼요.

if nil
  puts "nil is truthy"
else
  puts "nil is falsey"
end

# => nil is falsey

따라서 nil을 가질 수 있는 변수의 값이 nil이면 참인 분기는 실행되지 않아요.

foo = "boo"[2]? # It is possible that foo is nil
if foo
  p foo.class # => Char
end

nil인지 확인하기

Crystal에는 값이 nil인지 확인할 때 쓸 수 있는 메서드가 있어요. nil?라고 하며, 모든 객체에서 사용할 수 있어요.

foo = "boo"[2]?
if foo.nil?
  puts "foo is nil"
else
  puts "foo is not nil"
end

값을 그냥 if문에서 쓸 때와는 조금 달라요. 앞의 예시에서는 false와 nil이 둘 다 거짓으로 취급됐어요. 하지만 여기서는 nil만 거짓으로 취급돼요. 값이 false라면 nil이 아니어서 참으로 평가됐을 테니까요.

or 연산자

nil 값을 다루는 가장 쉬운 방법은 애초에 값이 nil이 되지 않도록 하는 거예요. or 연산자(||)는 Bools를 다룰 때 자주 쓰이지만, 제대로 이해하면 nil 값을 다룰 때도 쓸 수 있어요. or 연산자는 첫 번째 값이 참인지 확인하고, 참이 아니면 두 번째 값을 사용해요. 이 성질을 이용하면 값이 nil일 때 거짓으로 평가되어 두 번째 값이 사용되도록 만들 수 있어요.

"foo"[10]? || "bar" # => "bar"

지침

폐하께서는 칼마르 연합의 수도 코펜하겐에서 만찬을 열어요. 올해 가장 큰 파티이고, 모든 귀족이 초대되었어요. 그런데 폐하를 독살하려는 음모가 있다는 소문이 나라 전역에 퍼지고 있어요.

폐하께서는 왕실의 독 감별사인 여러분에게 음식이나 음료에 독이 들었는지 알아봐 달라고 부탁하셨어요. 폐하께서는 음식으로는 Mushroom pasties만 내놓을 예정이지만, 음료는 여러 종류를 준비하고 있어요.

1. 음식이 맞는지 확인해요

폐하께서 주문하신 음식이 아니면 독이 들었을 가능성이 높아요. 폐하께서 주문하신 음식이 아니면 버려야 해요.

food라는 인자를 받아 음식의 이름을 String으로 담는 check_food? 메서드를 구현해요. 메서드는 음식이 Mushroom pasties이면 그 음식을 반환하고, 그렇지 않으면 nil을 반환해야 해요.

CastleDinner.check_food?("Mushroom pasties")
# => "Mushroom pasties"

CastleDinner.check_food?("Bread")
# => nil

2. 음료에 독이 들었는지 확인해요

음료에도 독이 들었을 수 있지만, 그런지 알아내기는 조금 더 어려워요. 이름에 i라는 글자가 없으면 독이 든 음료예요. 대소문자는 상관없어요. 독이 든 음료는 버려야 해요.

drink라는 인자를 받아 음료의 이름을 String으로 담는 check_drink? 메서드를 구현해요. 메서드는 음료에 독이 들지 않았으면 그 음료를 반환하고, 그렇지 않으면 nil을 반환해야 해요.

CastleDinner.check_drink?("Apple juice")
# => "Apple juice"

CastleDinner.check_drink?("Tea")
# => nil

3. 음료를 바꿔요

폐하께서는 손님들이 음식에 독이 들었을까 걱정하게 하고 싶지 않으세요. 따라서 음료에 독이 들었으면 새 음료, 그러니까 Apple juice로 바꿔야 해요.

drink라는 인자를 받아 음료의 이름을 String으로 담는 replace_drink 메서드를 구현해요. 메서드는 음료에 독이 들지 않았으면 그 음료를 반환하고, 그렇지 않으면 "Apple juice"를 반환해야 해요.

CastleDinner.replace_drink("Orange juice")
# => "Orange juice"

CastleDinner.replace_drink("Tea")
# => "Apple juice"
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Crystal Exercism

성의 만찬 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Crystal 트랙을 개념 26개연습 문제 142개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.