언어 자체에 대한 글을 쓰는건 굉장히 오랜만인 것 같습니다. 오늘은 루비의 심볼에 대한 이야기를 하려합니다.
루비러라면 잘 아시겠지만, 루비는 모든것이 객체입니다. 그래서 일반적으로 객체라고 생각되지 않는 것들(문자열, 상수 등등) 또한 모두 객체입니다. (다른 언어도 비슷비슷하죠)
객체를 사용하기 위해서는 각 객체의 initialize를 통해
예를들어 루비 코드에 “GET” 이란 문자열이 5번 사용되었다고 칩니다. 이러면 이 프로그램이 실행되는 동안 “GET” 이란 문자열의 객체가 한번 생성되어 재 사용되는 것이 아닌, 각각 사용될 때 마다 String 객체를 생성하고 메모리를 잡아먹게 됩니다.
이래서 루비에서 적용된 개념은 심볼입니다.
Symbol?
심볼은 immutable, 즉 변경이 불가능한 객체입니다. 한번 생성되면 해당 객체 자체의 값을 변경할 수 없어지며, 동일한 이름으로 여러 부분에 사용될 수 있습니다.
심볼은 문자 앞에 콜론으로 표기하여 선언합니다. 예를들면.. A라는 심볼을 만들면
|
|
가 되겠지요.
그럼 아까 위에 이야기를 이어서 해보죠. :GET이란 문자열 대신에 심볼로 만들게 되면 5번 사용될 동안 같은 심볼 객체를 참조하게 됩니다. 위에 문자열로 5번 사용하는 것 보다 공간을 절약하게 됩니다. 물론 5번 잡히나 1번 잡히나 크진 않습니다. 그렇지만, 사용되는 구간이 많아질수록 루비 인터프리터는 점점 많은 메모리를 할당하게 될거고, 결국은 성능에 문제를 끼칠 수 있습니다.
irb로 확인해보죠.
|
|
각 객체의 주소인 object_id 값으로 비교하면, 문자열의 경우 데이터(“abcd”)는 같지만, 실제 객체가 할당된 주소는 다릅니다. 반대로 심볼(:abcd)은 동일한 객체를 사용하게 되죠.
실행되고 있는 상태에서의 심볼은 Symbol 객체를 이용해서 확인이 가능합니다.
|
|
Symbol을 String 처럼 사용하기
심볼은 한번 지정되면 변수에 문자열 데이터가 들어왔을 때 해당 변수의 문자열을 새로 만들지 않고 심볼을 참조하게 됩니다.
|
|
마치 심볼과 문자열이 다르게 선언되었을 것 같지만, intern으로 심볼 자체의 기호를 보면 :abcd를 가리키고 있습니다.
|
|
Conclusion
결국은 어디서 사용하는가가 가장 중요한 부분일텐데, 구글링 해보면 많이 나오겠지만, 대체로 해시의 키값에 대한 이야기를 합니다. 계속 반복되는 String 생성이 있는 부분에선 String을 직접 만드는 것 보다 심볼로 정의해서 사용하는게 메모리나 성능적인 부분에서 이득이 됩니다.
추가로.. 심볼 가지고 놀던 중 알게되었는데, def로 선언하면 해당 객체 또한 심볼로 정의됩니다.
|
|
재미있군요 :)
Reference
http://www.troubleshooters.com/codecorn/ruby/symbols.htm#_How_are_symbols_implemented https://ruby-doc.org/core-2.2.0/Symbol.html