심볼은 값을 가리키는 데 사용할 수 있는, 이름이 붙은 식별자예요.
심볼은 이름 앞에 : 문자를 붙이는 심볼 리터럴로 만들어요. 예를 들어 :foo처럼요.
따옴표로 감싸서 :"foo"처럼 쓸 수도 있는데, 이렇게 하면 이름에 공백을 넣을 수도 있어요.
:foo # => :foo
:"foo boo" # => :"foo boo"
심볼은 해시의 키를 비롯해 메서드 이름이나 변수 이름을 나타낼 때 등 언어 곳곳에서 사용해요.
심볼이 문자열과 다른 점은 데이터나 텍스트가 아니라 식별자라는 거예요. 그래서 이름이 같은 두 심볼은 언제나 같은 객체예요.
"foo".object_id # => 60
"foo".object_id # => 80
:foo.object_id # => 1086748
:foo.object_id # => 1086748
심볼은 불변이에요. 즉, 수정할 수 없어요. 그래서 심볼을 "수정"한다고 해도 실제로는 새로운 심볼을 만드는 거예요. 심볼을 다루는 데 쓸 수 있는 메서드가 몇 가지 있는데, 모두 새로운 심볼을 반환해요. 모든 메서드는 Symbol API에서 확인할 수 있어요.
:foo.upcase # => :FOO
:foo.object_id # => 1086748
:foo.upcase.object_id # => 60
심볼이 불변이라는 점의 장점은 문자열보다 메모리를 효율적으로 쓴다는 것, 그리고 식별자로 쓰기에 더 안전하다는 것이에요.
심볼은 문자열로 바꿀 수 있고, 그 반대도 가능해요.
심볼을 수정하고 싶거나 심볼을 문자열로 쓰고 싶을 때 유용해요.
문자열을 심볼로 바꾸려면 String#to_sym 메서드를, 그 반대로 하려면 Symbol#to_s 메서드를 쓰면 돼요.
심볼에는 쓸 수 있는 메서드가 제한적이라, 새로운 심볼이 필요할 때 심볼을 문자열로 바꿔서 문자열 메서드를 사용하면 유용해요.
:foo.to_s # => "foo"
"foo".to_sym # => :foo
팔레르모 항구는 배들이 많이 오가는 분주한 항구예요. 오랫동안 항구에 현재 정박 중인 배들을 관리하는 수동 시스템을 사용해 왔어요. 이 시스템은 오류가 발생하기 쉬워서, 항구 책임자는 이를 전산 시스템으로 교체하기로 했어요.
항구 책임자는 새로운 시스템을 구현하도록 여러분을 고용했어요. 이 시스템은 배의 식별자뿐만 아니라 목적지의 식별자도 처리해야 해요.
가장 먼저 팔레르모 항구의 식별자를 만들어야 해요. 식별자는 항구 이름의 첫 네 글자를 대문자로 쓴 것이에요.
Port::IDENTIFIER 상수를 값이 :PALE인 심볼로 정의해요.
Port::IDENTIFIER
# => :PALE
프로그램은 다른 항구도 처리해야 하므로, 그 항구들의 식별자도 만들어야 해요. 항구에서는 시스템이 자동화되기를 바라고, 항구마다 이름 붙이는 규칙이 다르기 때문에 식별자는 항구 이름에서 생성되어야 해요. 식별자는 항구 이름의 첫 네 글자를 대문자로 쓴 것이에요.
Port.get_identifier 메서드는 문자열을 인자로 받아, 그 항구의 식별자를 심볼로 반환하도록 정의해요.
Port.get_identifier("Hamburg")
# => :HAMB
항구에는 터미널이 두 개 있고, 시스템은 배가 어느 터미널에 정박해야 하는지 판단해야 해요. 터미널은 배의 식별자로 결정돼요.
식별자는 두 부분으로 이루어져 있어요. 첫 번째 부분은 배가 어떤 화물을 운반하는지 나타내는 대문자 세 글자이고, 그다음은 배의 고유 식별자인 숫자 세 자리예요.
배의 식별자에 담긴 화물이 OIL 또는 GAS라면, 배는 A 터미널에 정박해야 해요. 그렇지 않으면 배는 B 터미널에 정박해야 해요.
Port.get_terminal 메서드는 배의 식별자인 심볼을 인자로 받도록 정의해요.
이 메서드는 터미널을 심볼로 반환해야 해요.
Port.get_terminal(:OIL123)
# => :A
Exercism에 가입하고 Ruby 트랙을 개념 21개연습 문제 121개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.