Showcase Gem에서 showcase.sample 메서드는 Showcase::Preview 인스턴스의 @samples 인스턴스 변수를 채워 최종 뷰로 전달합니다. 이 과정에서 Showcase::Sample 인스턴스가 생성되며, evaluate 메서드가 호출되어 샘플 렌더링의 핵심 로직을 실행합니다.
evaluate 및 consume 메서드
evaluate 메서드 내에서는 block.arity를 통해 블록이 인수를 기대하는지 확인한 후, consume 메서드를 호출합니다. consume 메서드는 다음 두 가지 주요 작업을 수행합니다.
-
render메서드:ActiveSupport::Notifications를 사용하여render_partial.action_view이벤트를 구독합니다. 이를 통해 컴포넌트 렌더링 시 발생하는duration및allocation정보를 측정하여 뷰에 표시합니다. -
extract_source메서드: 블록의 소스 코드를 추출합니다. 이 메서드는block.source_location을 사용하여 파일 경로와 라인 번호를 얻고,extract_source_block_via_matched_indentation_from메서드를 호출하여 실제 소스 코드 블록을 식별하고 추출합니다.
소스 코드 추출 (extract_source_block_via_matched_indentation_from)
extract_source_block_via_matched_indentation_from은 복잡한 로직을 통해 블록의 소스 코드를 정확히 추출합니다.
-
File.readlines(file)로 파일을 읽어옵니다. -
slice(source_location_index.pred..)를 사용하여 블록이 정의된 라인부터 시작하는 라인들을 가져옵니다. -
starting_line의 선행 공백(indentation)을 파악합니다. -
동일한 들여쓰기로 시작하는 라인 중 블록의
end키워드를 찾아index를 얻습니다. -
lines.slice!(index..)로end키워드 이후의 라인들을 제거합니다. -
남은 라인들을 문자열로 변환하고 불필요한 공백을 제거하여 최종 소스 코드를 얻습니다.
문법 강조 (Showcase.sample_renderer와 Rouge Gem)
추출된 소스 코드는 Showcase.sample_renderer를 통해 문법 강조 처리됩니다. 기본적으로 rouge Gem이 사용되며, gemspec에 명시되어 있지 않아 LoadError 발생 시 문법 강조 없이 원본 소스를 반환하는 proc이 사용됩니다. Showcase.sample_renderer는 instance_exec를 사용하여 @view_context의 컨텍스트에서 실행되므로, sanitize나 link_to와 같은 뷰 헬퍼 메서드를 렌더러 내에서 활용할 수 있는 유연성을 제공합니다.
뷰 렌더링
이러한 과정을 거쳐 Showcase::Sample 인스턴스의 인스턴스 변수들은 뷰 렌더링에 필요한 모든 데이터를 포함하게 됩니다. 뷰에서는 showcase/engine/sample 부분 템플릿을 사용하여 샘플의 이름, 렌더링 시간, 할당량, 실제 컴포넌트의 HTML, 그리고 소스 코드를 표시합니다.