개발 동기
기존 루비 YAML 파서의 문제점은 psych-pure 개발의 주요 동기가 되었습니다.
-
사양 불일치: 루비에서 사용되는
libyaml기반의Psych젬은 YAML 1.2 사양의 많은 테스트 케이스에서 오류를 발생시키며,matrix.yaml.info에 따르면 사양을 완전히 준수하는 파서는 매우 드뭅니다. -
주석 손실:
libyaml은 파싱 과정에서 주석을 폐기하여, YAML 문서를 로드, 수정, 덤프할 때 모든 주석이 손실되는 문제가 있었습니다. 이는 여러 차례 논의되었으나, 정규 표현식 기반의 해결책으로는 문법의 복잡성을 제대로 처리할 수 없었습니다. -
크로스 플랫폼 한계:
libfyaml은 사양 준수율이 높지만 윈도우를 지원하지 않아, 순수 루비 구현 또는libfyaml의 윈도우 지원이 필요한 상황이었습니다. 저자는 후자를 선택하여 순수 루비 구현을 목표로 했습니다.
구현 과정
psych-pure의 구현은 여러 단계에 걸쳐 진행되었습니다.
-
기반 구조: GitHub의
yaml조직에 있는yaml-reference-parser프로젝트를 기반으로 시작했습니다. 이 프로젝트는 언어에 구애받지 않는 YAML 1.2 사양 준수 파서 템플릿을 제공합니다. -
성능 최적화: 초기 생성된 파서는 비효율적이어서, 메서드 인라인화 및 코드 재배치를 통해 합리적인 성능 수준으로 최적화하는 데 상당한 시간을 투자했습니다.
- 테스트 및 검증:
yaml조직의yaml-test-suite를 사용하여 구현을 검증했습니다.- 테스트 실행을 위해
testml에 루비 지원을 추가하는 작업도 병행하여, 전체 테스트 스위트를 통해 사양 준수 여부를 확인했습니다.
- 주석 보존 기능:
Prism파서와Prettier포맷터의 접근 방식을 따라, 문서 파싱 후 AST를 탐색하여 노드들의 선행, 후행, 포함 주석을 결정하고 첨부하는 방식을 채택했습니다.- 주석을 올바른 위치에 다시 배치하기 위해 자체 YAML 이미터를 개발해야 했습니다.
- 로드된 객체(예: 해시, 배열)가 YAML로 다시 덤프될 때 주석을 유지하도록 사용자 정의 델리게이터 클래스로 래핑하는 작업이 필요했습니다. 특히 해시의 경우 모든 변경 메서드를 재구현해야 하는 번거로움이 있었습니다.
- API 호환성:
Psych::Pure가Psych의 드롭인 대체품으로 기능하도록Psych의 공개 API를 복사하여, 기존Psych방문자나 핸들러가Psych::Pure에서도 작동하도록 했습니다.