루비 코드를 작성할 때, 예를 들어 다음과 같은 간단한 메서드를 정의한다고 가정해봅시다.
ruby
def greet(name)
  puts "Hello, #{name}"
end
루비의 파서는 이 코드를 즉시 실행하지 않습니다. 대신, 코드가 어떻게 구성되어 있는지를 나타내는 트리 형태의 구조로 먼저 분석합니다. 이것이 바로 AST입니다. AST는 코드의 순수한 구조적 표현이며, 각 노드는 소스 코드의 구문 요소를 나타냅니다.
루비에서 AST 확인하기
루비는 내장 파서인 Ripper를 통해 코드의 AST를 직접 확인할 수 있는 기능을 제공합니다. 다음 예시 코드를 통해 Ripper.sexp 메서드를 사용하여 AST를 생성하고 출력하는 방법을 살펴보겠습니다.
```ruby require ‘ripper’ require ‘pp’
code = ‘def greet(name); puts “Hello, #{name}”; end’ pp Ripper.sexp(code) ```
위 코드를 실행하면 다음과 유사한 형태의 AST 결과가 출력됩니다.
[:program,
  [[:def,
    [:@ident, "greet", [1, 4]],
    [:paren, [[:@ident, "name", [1, 10]]]],
    [:bodystmt,
      [[:command,
        [:@ident, "puts", [1, 17]],
        [:args_add_block,
          [[:string_literal,
            [:string_content,
              [:@tstring_content, "Hello, ", [1, 23]],
              [:string_embexpr,
                [[:var_ref, [:@ident, "name", [1, 32]]]]
              ]
            ]
          ]],
          false
        ]
      ]],
      nil, nil, nil
    ]]]
AST 구조 분석
이 AST는 다음과 같은 코드의 구조적 정보를 명확하게 보여줍니다.
- 
    
greet이라는 이름의 메서드가 정의되어 있습니다. - 
    
이 메서드는
name이라는 하나의 파라미터를 가집니다. - 
    
메서드 본문에서는
puts명령을 호출합니다. - 
    
puts명령에 전달되는 인자는Hello, #{name}과 같은 문자열 보간(string interpolation)을 포함하는 문자열 리터럴입니다. - 
    
문자열 보간 안에는
name파라미터가 변수로 참조되어 사용됩니다. 
이처럼 AST는 코드를 실행하기 전에 코드의 의미론적 구조를 파악하고, 컴파일러, 린터, 코드 포매터 등 다양한 개발 도구에서 코드 분석의 기초 자료로 활용됩니다.