RuboCop に興味が出たので Ast を眺めてみた

こんにちは kk8511 です。

最近ふとRuboCopに興味が出たのでCopの実装方法を調べていました。

Development :: RuboCop Docs

Ast を眺めただけで力尽きましたが備忘録として記載します。

AST

RuboCop では Abstract Syntax Tree (AST) が利用されるので、まずruby-parseコマンドでサクッと AST を確認してみました。

値には型がつく。

% ruby-parse -e '1'
(int 1)

% ruby-parse -e '"hello"' 
(str "hello")

% ruby-parse -e '[1,2,3]'                         
(array
  (int 1)
  (int 2)
  (int 3))

メソッドチェーン

メソッドチェーンは send のネストになっている。

% ruby-parse -e '(-1.2).floor.abs'
(send
  (send
    (begin
      (float -1.2)) :floor) :abs)

ブロック

ブロックはメソッドの send を囲む形になっている。

% ruby-parse -e '3.times { puts "Hello" }'
(block
  (send
    (int 3) :times)
  (args)
  (send nil :puts
    (str "Hello")))

% ruby-parse -e '3.times {|i| puts "Hello #{i}" }'
(block
  (send
    (int 3) :times)
  (args
    (procarg0
      (arg :i)))
  (send nil :puts
    (dstr
      (str "Hello ")
      (begin
        (lvar :i)))))

おわりに

今まで Ruby を含め、どの言語でも AST を意識したことはなかったため興味深かったです。

RuboCop を触るつもりが Ast を眺めただけで満足してしまったので、ひとまずここまでとなります。

(そもそも、既存のCopが色々とあるので、自前で実装する日は来るだろうか......)