Rubocop은 각 파일을 검사할 때 세 가지 주요 단계를 거칩니다. 첫째, 코드의 구조를 표현하는 AST(Abstract Syntax Tree)를 구축합니다. 둘째, 이 AST의 각 노드를 순회하며 설정된 Cop들을 호출합니다. 셋째, Cop들은 코드 위반 사항(offenses)을 추가하고 필요한 경우 자동 수정을 수행합니다.
간단한 커스텀 Cop 개발의 예시로, !array.empty?
와 같은 패턴을 array.any?
로 자동 수정하는 Cop 구현 과정을 소개합니다. 이는 Cop::Base
를 상속받아 메시지를 정의하고, AST 노드를 처리하는 on_send
메서드를 구현하는 방식으로 이루어집니다. 특히 def_node_matcher
매크로를 활용하여 특정 노드 패턴(!object.empty?
)을 효율적으로 매칭할 수 있습니다. 자동 수정 기능을 추가하려면 Autocorrectable
모듈을 확장하고, 노드의 리시버를 캡처한 뒤 블록 문법을 사용하여 전체 노드를 원하는 소스 코드로 교체하는 과정을 거칩니다. 이는 IDE에서 시각적인 피드백과 함께 저장 시 자동 수정이 이루어지는 편리함을 제공합니다.
더 나아가, AST만으로는 파악하기 어려운 템플릿 메서드(상위 클래스에서 정의되고 하위 클래스에서 오버라이드되는 메서드)를 식별하기 위한 고급 Cop 개발 기법을 제시합니다. 이는 두 단계로 진행됩니다. 첫 번째 단계에서는 애플리케이션 파일을 로드하여 런타임 정보(모든 메서드 정의 포함)를 추출합니다. 예를 들어, 클래스를 로드하고 기본 클래스와 서브클래스를 분류한 뒤 공유 메서드를 수집하여 YAML 형태로 저장할 수 있습니다. 두 번째 단계에서는 이렇게 추출된 정보를 커스텀 Cop에서 효율적으로 활용합니다. Rubocop 내에서 외부 데이터를 한 번만 로드하도록 on_new_investigation
을 사용하여 각 파일 처리 시점에 관련 메서드 정보를 로드합니다. 이후 on_def_node
를 사용하여 메서드 정의를 만날 때마다 해당 메서드 이름이 미리 추출된 템플릿 메서드 목록에 포함되는지 확인하여 위반 사항을 등록합니다. 이러한 접근 방식은 특정 메서드가 여러 클래스에서 오버라이드되고 있음을 시각적으로 강조하여 개발자가 복잡한 코드 구조를 이해하는 데 큰 도움을 줍니다.