こんにちは kk8511 です。
最近ふとRuboCopに興味が出たのでCopの実装方法を調べていました。
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が色々とあるので、自前で実装する日は来るだろうか......)