루비에서의 느낌표(!)
의미
루비의 API 문서를 보면 아래와 같이 동일한 이름에 느낌표(!, Exclamation mark)만 붙은 메서드쌍을 많이 발견할 수 있다. 일반적으로 느낌표로 끝나는 메서드는 해당 메서드가 호출된 객체를 수정할 것이라는 의미를 담고 있다. 편리한 기능이지만 해당 객체를 다른 곳에서 참조하고 있는 경우 오류의 원인이 될 수 있어 Dangerouse Methods라고 불린다. 반대로 느낌표가 없고 호출한 객체는 변경되지 않고 복사본에 변경 사항이 적용되는 일반 메서드를 Safe Methods라고 한다.
Safe Methods | Dangerous Methods |
gsub | gsub! |
reverse | reverse! |
strip | strip! |
upcase | upcase! |
sort | sort! |
select | select! |
예시1: Sort 메서드
일반 sort 메소드를 사용하여 배열을 정렬해 보자. 메서드를 실행하였지만 Safe Methods는 원본 객체에 영향을 주지 않기 때문에 a의 원본은 정렬이 되지 않은 상태이다. 이때 a의 원본 데이터를 변경하고자 한다면 대입 과정이 필요하다.
>> a
=> [42, 8, 17]
>> a.sort
=> [8, 17, 42]
>> a
=> [42, 8, 17] # a의 원본 내용은 그대로이다.
그렇다면 이와 쌍을 이루는 Dangerous Methods인 sort!로 배열을 정렬해보자. a의 원본 데이터가 정렬된 것을 확인할 수 있다.
>> a
=> [42, 8, 17]
>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42] # a의 원본 데이터가 변경되었다.
예시 2: Downcase 메서드
문자열을 소문자로 변경하는 downcase 메서드를 사용해보자. 소문자로 문자열의 내용을 변경해 주지만 원본 데이터는 그대로인 것을 확인할 수 있다.
>> foo
=> "A STRING"
>> foo.downcase
=> "a string"
>> foo
=> "A STRING" # foo의 원본 데이터에는 영향이 없다.
그렇다면 쌍을 이루는 Dangerous Methods인 downcase!를 문자열에 적용해 보자. 원본 데이터에도 영향이 간 것을 확인할 수 있다.
>> foo
=> "A STRING"
>> foo.downcase!
=> "a string"
>> foo
=> "a string" # foo의 원본 데이터에도 영향이 있다.
참고 자료 및 사이트
- https://stackoverflow.com/questions/612189/why-are-exclamation-marks-used-in-ruby-methods