今日作っていた cop で調べたログ。
グローバル変数 $stderr
を Parser gem による S 式で表現すると以下のようになる。S 式の比較のため、引数が複数あるパターンと引数のないパターンを挙げておく。ちなみに ruby_ast_visualizer は自作の gem で Parser gem の出力表示を得ることができるラッパーコマンドとして使っている。
% ruby_ast_visualizer -e "$stderr.puts('foo', 'bar')" (send (gvar :$stderr) :puts (str "foo") (str "bar"))
% ruby_ast_visualizer -e "$stderr.puts" (send (gvar :$stderr) :puts)
このグローバル変数 $stderr
を RuboCop の def_node_matcher
に渡す S 式で表現する場合、$
という記号はマッチした値をキャプチャする意味で使われているためそのまま使えない。代わりに #
でメソッド呼び出しにする。
def_node_matcher :stderr_puts?, <<-PATTERN (send (gvar #stderr_gvar?) :puts ...) PATTERN
対応するメソッドの方でマッチするか判定させる。
def stderr_gvar?(sym) sym == :$stderr end
他の cop 実装がサンプルコードになっているので、このあたり gvar
で grep して他に類似のケースでどうしているかを調べてみていた。
追記 pocke さんから Twitter でコメントを頂く。
https://t.co/skN7kfZrlV
— Pocke(ぽっけ) (@p_ck_) 2017年10月1日
これでテスト全部通ってるし、動くんじゃないだろうか(たぶん)