티스토리 뷰

Ruby

Ruby의 Symbols과 String의 차이

강씨아저씨 2018. 4. 21. 01:58

아래 내용은 루비가이드의 포스팅 내용은 번역한 글입니다.(https://www.rubyguides.com/2018/02/ruby-symbols/)


Symbol 과 String 의 차이에 대해서 생각해보신적 있으신가요?

오늘은 그 차이에 대해 알아볼 예정입니다. 



가장큰 차이로는 String은 데이터로써 사용됩니다. 그리고 Symbol 은 식별자로 사용됩니다. 

Symbol은 String 과는 다른용도로 사용되며 절대 단순한 Frozen String이 아닙니다. 


언제 Symbol 을 사용해야 할까?

Symbol이 일반적으로 사용될때는 Method나 인스턴스 변수의 이름을 표현할때 입니다. 


Example:


:title 이라는 Symbol은 @title 인스턴스 변수를 의미합니다.


또한 hash의 key로 Symbol 을 사용 할 수 있습니다. 


Example:


hash 의 key로 symbol 을 사용할때의 이점은 key값에 대한 가독성이 좋고 변경이 불가능합니다. 또한 String key와 Symbol의 밴치마킹(https://gist.github.com/matugm/410f46ca87455b2701faa9a88edee8df) 결과를 보면 아시겠지만 String이 Symbol에 비해서 약 1.7배 느리게 동작합니다. 


Symbol은 또한 메타프로그래밍에서 사용할 수 있습니다.

Symbol 은 이름이나 메소드를 표현할때 사용하고 데이터로 사용될때는 String 을 사용해야 합니다. 

String 과 Symbol 을 변환하기


가끔 어떠한 메소드 호출시 반환값으로 Symbol이 반환될때가 있습니다. 그런데 이러한 Symbol 을 다른 문자열과 비교나 String의 Operation 을 사용하기 위해서 String 으로 변환해야 할때가 있습니다. 



이럴때는 to_s 메소드를 사용하면 됩니다. 


예를 들어 method_missing 메소드를 사용할때 첫번째 매개변수가 method_name을 의미하는 Symbol 입니다. 

이 상황에서 method_name이 특정패턴에 일치하는지 확인하기 위해서 to_s 메소드를 사용합니다.

Example:



또한 String의 to_sym 메소드를 사용하면 Symbol 로도 변경 할 수 있습니다. 



Symbol 의 배열을 만들고 싶을때는 아래와 같이 사용하면 됩니다. 

이렇게 할 경우 별도의 콜롬(:) 과 쉼표(,)를 입력하지 않아도 Symbol 배열을 만들수 있습니다.


또한 String 배열을 만들때는 아래와 같이 사용하면 됩니다. 



Symbol 의 1GC


Symbol 에 대한 흥미로운 사실은 여러가지 타입의 Symbol 이 존재한다는 겁니다. 


Ruby 2.2 버전 이전에는 Symbol 이  GC 를 해도 메모리가 해제되지 않았습니다.

즉 Ruby의 일반적인 객체들처럼 더이상 필요하지 않으면 메모리를 해제해야 하지만 해제하지 않고 메모리상에 계속 남아있었습니다.


예를들면 아래와 같습니다.


위의 예시를 보시면 아시겠지만 GC를 했는데도 전체 Symbol 의 숫자가 10이 증가했습니다. 


Ruby 2.2 버전 이후로는 Symbol이 일반적인 객체들처럼 더이상 사용되지 않을경우 GC에 의해서 메모리가 해제됩니다. 


그러나 immortal symbols 라 불리는 일부 Symbol 들은 여전히 GC에 의해서 메모리가 해제되지 않습니다. 


이러한 정보는 ObjectSpace 모듈 을 사용해서 확인해 볼 수 있습니다(http://ruby-doc.org/core-2.4.0/ObjectSpace.html)



:a1 처럼 Symbol 을 직접 선언할 경우 이 Symbol 은 자동으로 immortal symbol 이 됩니다.

new 메소드를 이용해서 Symbol 을 생성한 경우 immortal_statis_symbol 타입으로 생성합니다. 


그렇다면 GC에 의해 메모리가 해제되는 Symbol 은 어떻게 선언해야 할까요?


앞서 설명드린 String 을 Symbol 로 바꾸는 to_sym 을 이용해서 Symbol 을 생성할 경우에는 GC에 의해 메모리가 해제되는 mortal symbol이 됩니다. 


immortal_dynamic_symbol 의 경우는 mortal symbol 에서 immortal 한 symbol로 변경되었을때 입니다. 

어떠한 경우 이런일이 있을까요? mortal symbol 을 함수로 만들때 이러한 변경이 발생합니다. 


(Symbol 의 타입에 대해서는 조금더 확인해볼 필요가 있겠네요~)


누군가에게 도움이 되었기를 바라면서 오늘의 포스팅 끝


댓글