Ruby의 패턴 매칭은 중첩된 해시 및 배열 구조 내에서 특정 조건을 만족하는 요소를 찾아내고 그 값을 추출하는 데 매우 유용합니다. 다음은 role이 ‘moderator’인 사용자의 email을 system 해시에서 찾는 예시를 통해 패턴 매칭의 동작 방식을 상세히 설명합니다.
ruby
system = {
users: [
{ username: 'alice', role: 'admin', email: 'alice@example.com' },
{ username: 'charlie', role: 'moderator', email: 'charlie@example.com' }
]
}
1. 요소 추출 방식 비교
- **전통적인 방식 (`Enumerator
find)**: system[:users].find { |u| u[:role] == ‘moderator’ }[:email]과 같이 배열을 순회하며 조건을 만족하는 요소를 찾고, 그 해시에서 email` 값을 추출합니다.
- 패턴 매칭 방식:
system => {users: [*, { role: 'moderator', email: }, *]}와 같이 패턴을 정의하여 일치하는email값을 직접 지역 변수email에 바인딩합니다. 여기서*는 배열의 나머지 요소를 의미하며,email:은 일치하는 해시의email값을 해당 이름의 변수에 할당합니다. 이 방식은 코드를 훨씬 간결하게 만듭니다.
2. 오류 처리의 차이점
패턴 매칭은 전통적인 방식과 다른 오류 처리 메커니즘을 가집니다.
-
find방식: 일치하는 요소를 찾지 못하면nil을 반환하고, 이nil에 대해[:email]과 같은 메서드를 호출하려 할 때NoMethodError가 발생합니다. -
패턴 매칭 방식: 패턴과 일치하는 요소를 찾지 못하면
NoMatchingPatternError를 명시적으로 발생시켜, 패턴 매칭 실패를 직접적으로 알립니다. 이는 오류의 원인을 더 명확하게 파악할 수 있도록 돕습니다.
3. 변수 바인딩 동작
패턴 매칭에서 email:과 같이 콜론과 함께 변수 이름을 사용하는 것은 특별한 동작을 합니다.
-
새로운 변수 생성: 만약
email이라는 지역 변수나 메서드가 현재 스코프에 존재하지 않으면, 패턴 매칭은 일치하는 값으로 새로운 지역 변수email을 생성하고 값을 할당합니다.ruby system => {users: [*, { role: 'moderator', email: }, *]} # `email` 변수가 없었다면 새로 생성되어 'charlie@example.com'이 할당됩니다. -
기존 변수 값과의 일치 확인:
email이라는 변수가 이미 존재하면, 패턴 매칭은 해당 키의 값과 기존email변수의 값이 일치하는지 확인합니다.ruby email = 'charlie@example.com' # 변수가 이미 존재 system => {users: [*, { role: 'moderator', email: }, *]} # 기존 email 변수 값과 일치하므로 매칭 성공, 변수 값 유지만약 기존 변수의 값과 패턴 매칭으로 찾은 값이 일치하지 않으면,NoMatchingPatternError가 발생합니다. 이는 패턴 매칭이 단순히 값을 추출하는 것을 넘어, 특정 값이 존재하는지 여부까지 검증하는 강력한 기능을 제공함을 의미합니다.