从 Ruby 块中提取 AST

问题描述:

是否可以从 Ruby 本身获取块的 AST?

Is it possible to grab the AST of a block from Ruby itself?

我已经查看了 ParseTree 和 ruby​​_parser,但它们似乎都对 Ruby 1.9.2 提供了粗略的支持(根据我读过的内容).我需要一些与 1.9.2 兼容的东西.

I've had a look at both ParseTree and ruby_parser, but they both seem to have sketchy support (from what I've read) for Ruby 1.9.2. I need something that works well with 1.9.2.

开箱即用的 Ripper 包含在 MRI 1.9 中.

Ripper is included in MRI 1.9 out of the box.

ruby-1.9.2-p180 :004 > require 'ripper'
 => true
ruby-1.9.2-p180 :005 > Ripper.sexp("def a; end")
 => [:program, [[:def, [:@ident, "a", [1, 4]], [:params, nil, nil, nil, nil, nil], [:bodystmt, [[:void_stmt]], nil, nil, nil]]]] 

在 1.8 中,Ruby 通过遍历 AST 来执行代码,因此可以获取给定方法/块的 AST.在 1.9 中并非如此;代码首先被解析,然后转换为 YARV 字节码,然后执行.不是源代码,也不是在翻译步骤之后保留AST,并且后者是不可逆的;因此,您无法在 1.9 中获得块的 AST.

In 1.8, Ruby executes the code by traversing the AST, so it is possible to get the AST for a given method/block. In 1.9 it is not so; the code is first parsed, then converted to YARV bytecode, and then executed. Not the source, nor AST is kept after the translating step, and the latter is not reversible; hence you cannot get the AST for a block in 1.9.