오늘은 배열, 해시 또는 Enumerable 모듈을 포함하는 모든 객체에 대해 조건문을 검사할 때 유용하게 쓰이는 4가지 Enumerable 메서드를 알아보겠습니다.

이 4가지 메서드는 모두 true 또는 false를 반환합니다.
Ruby all? 메서드
배열 안의 모든 문자열이 특정 길이를 갖고 있는지 확인하고 싶다고 가정해 봅시다.
전통적인 방식
def all_words_have_specific_size?(words)
return false if words.empty?
words.each do |str|
return false unless str.size == 5
end
true
end
words = ["bacon", "orange", "apple"]
all_words_have_specific_size?(words)
# false
위 코드는 문자열을 하나씩 검사하면서, 길이가 조건과 다르면 false를 반환하고 끝까지 통과하면 true를 반환합니다.
단순한 확인 작업인데도 코드가 꽤 깁니다. 이런 검사를 할 때마다 매번 이렇게 작성해야 한다면 상당히 번거로울 것입니다.
사실 우리가 실제로 관심 있는 부분은 딱 한 줄입니다.
str.size == 5
바로 검사하려는 조건 자체죠. 더 좋은 방법이 있을까요?
all? 메서드 활용하기
네, 있습니다! all? 메서드를 사용하면 복잡한 반복 로직을 직접 작성하지 않아도 됩니다.
strings.all? { |str| str.size == 5 }
이게 전부입니다. 코드가 훨씬 간결하고 의도도 명확해집니다.
all?과 빈 배열
반드시 알아두어야 할 중요한 특징이 하나 있습니다.
all? 메서드를 빈 배열에 호출하면 true가 반환됩니다.
예시:
[].all? { |s| s.size == 1 }
# true
설명: false인 요소가 하나도 없기 때문에, 논리적으로 '모든 요소가 참'이라고 판단되는 것입니다. 이는 수학의 공집합에 대한 보편 명제와 같은 원리입니다.
Ruby none? 메서드
all?의 반대 동작이 필요하다면 none?을 사용하세요.
예시:
strings.none? { |str| str.size == 5 }
조건에 맞는 문자열이 하나도 없으면 true, 하나라도 있으면 false를 반환합니다.
마치 if 문에서 unless를 쓰는 것과 비슷한 역할이라고 생각하면 이해하기 쉽습니다.
Ruby any? 메서드
요소 중 하나라도 조건에 맞는지 확인하고 싶다면 어떻게 해야 할까요? 바로 any? 메서드를 사용하면 됩니다!
예시:
[1,2,3,4,5].any? # true
이 예제에서 any?는 마치 empty?의 반대처럼 동작합니다. 하지만 모든 상황에서 그렇지는 않습니다.
왜냐하면 any?는 다음 질문에 답하기 때문입니다:
"이 배열 안에 truthy(참으로 평가되는) 값이 하나라도 있는가?"
배열에 truthy하지 않은 값(nil/false)만 들어 있다면 배열이 실제로 비어 있지 않더라도 false가 반환됩니다.
예시:
[nil].any? # false
물론 블록을 함께 전달할 수도 있습니다.
[1,2,3].any? { |n| n > 0 }
# true
이 코드는 최소한 하나의 요소에 대해 n > 0이 true인지 검사합니다.
Ruby one? 메서드
one? 메서드를 사용하면 정확히 하나의 요소만 조건을 만족하는지 확인할 수 있습니다.
예시:
["a", 1, {}].one? { |obj| obj.kind_of?(Hash) }
# true
블록 없이 사용하면, 배열에 truthy 값(false/nil이 아닌 값)이 정확히 하나만 있는지 검사합니다.
["a"].one? # true [].one? # false [nil].one? # false
개인적으로는 size == 1 방식을 선호합니다. one? 메서드는 그렇게 흔하게 사용되지 않기 때문에, 익숙하지 않은 개발자도 size == 1이라면 누구나 즉시 이해할 수 있어 더 명시적이기 때문입니다.
Ruby 2.5의 새로운 기능
Ruby 2.5부터는 이 4가지 메서드(any? / all? / none? / one?)에 grep처럼 인수를 전달할 수 있게 되었습니다.
예시:
[:orange, :apple, :coconut].any?(Symbol) # true [1,2,3].all?(1..10) # true
클래스, 정규표현식, 범위(range) 등을 검사할 때 아주 편리한 단축 기능입니다.
마무리
지금까지 개발 시간을 크게 절약해 줄 수 있는 4가지 강력한 Ruby 메서드를 살펴봤습니다. 이 메서드들은 모두 true 또는 false만 반환한다는 점도 기억하세요.
아직 이 메서드들을 사용해 보지 않으셨다면, 지금 바로 코드에 적용해 보는 건 어떨까요?