원문 캡처 · github.com
원문 캡처 · github.com

Ruby 파서 Prism이 v2.0.0을 출시했다. 성능과 메모리 사용량을 개선하고 Ruby 4.1 구문 지원, 공식 C++ 인터페이스, 플랫폼별 사전 컴파일 패키지를 추가했지만, 주요 버전 변경인 만큼 대부분의 변경 사항이 호환성을 깨뜨린다.

이번 버전은 구문 분석 기본값을 version: "latest"에서 version: "nearest"로 바꿨다. 이제 실행 중인 Ruby 버전이나 Prism이 지원하는 가장 가까운 버전의 구문으로 코드를 분석한다. 이전 동작을 유지하려면 version: "latest"를 지정해야 한다. 지원하지 않는 버전을 지정해도 오류를 내지 않고 가장 가까운 지원 구문 버전으로 대체하는 동작도 version: "nearest"에 포함됐다.

Ruby 4.1 구문 지원에는 메서드가 블록을 받지 않는다고 선언하는 &nil, 메서드 시그니처의 끝에 쉼표를 두는 문법, 무효 값 표현식 검사 개선 등이 포함됐다. END { break }와 END { next }는 거부하며, a /b/는 더 이상 모호한 / 경고를 내지 않는다.

새 기능으로는 구문 오류가 있는 코드를 전달할 때 SyntaxError를 발생시키는 raise_error 옵션, 코드를 더 추가하면 유효해질 수 있는지 확인하는 Prism::ParseResult#continuable, 메서드나 프로시저 등에 연결된 AST 노드를 찾는 Prism.find가 추가됐다. 주석을 구문 분석 중 노드에 연결하는 attach_comments 옵션도 지원한다. 연결된 주석은 Node#comments와 C API에서 확인할 수 있다. 그 밖에 Source#checksum, StringQuery#keyword?, Prism 노드를 대상으로 위치 구간을 기준으로 패턴 매칭하는 기능이 추가됐다. Prism.parse_file 등은 Pathname처럼 to_path에 응답하는 객체도 받는다.

호환성을 확인해야 할 주요 변경도 있다. 오류가 있는 구문에서 예상치 못한 노드를 감싸던 MissingNode는 ErrorRecoveryNode로 대체됐다. Prism.lex는 내부 파서 상태와 묶은 배열 대신 토큰 배열을 반환하며, 일부 토큰 종류도 더 세분화됐다. Ruby API에서는 Prism::Source.for의 두 번째·세 번째 위치 인수가 필수가 됐고, 주석은 소스에 저장된다. 기존의 ParseResult#attach_comments!와 여러 위치·노드의 주석 접근 메서드는 제거됐다.

C API에서는 노드를 제외한 대부분의 구조체가 불투명해지고 내부 함수 다수가 숨겨졌다. 위치 정보는 시작 오프셋과 길이를 담은 32비트 정수 쌍으로 표현되며, 대부분의 메모리 할당은 아레나를 사용한다. 방문자 콜백은 bool 대신 pm_visit_result_t를 반환한다. Rust에서도 위치 표현과 할당 방식이 바뀌고 Diagnostic::message의 반환형이 &str에서 &[u8]로 변경됐다. JavaScript의 파싱 메서드는 UTF-16으로 변환하는 방식 대신 Uint8Array만 받는다. Prism::Pack도 제거됐다.

배포판에는 문서 개선과 새 플레이그라운드, 완전한 RBS·RBI 정의, Ruby 개발자들이 소유하는 라이선스, 공식 C++ 인터페이스가 포함됐다. 변경 사항 전체는 Prism v2.0.0 릴리스 노트에서 확인할 수 있다.