既存のRubyのクラスの、テストコードgeneratorを作成する(1)
ちょっと機会があって、プログラムでRubyスクリプトを解析したいと思って調べています。まだまだ調査中なので中途半端な情報になってしまいますが、ご勘弁ください。
Rubyのソースコードを解析するためのソフトウェアとしては、Ruby標準添付のripperと、seatle.rb (http://www.seattlerb.org/) のruby_parserが有名ですので、それらを使うことを前提に調査しています。
- ripper: http://doc.ruby-lang.org/ja/2.0.0/library/ripper.html
- ruby_parser: http://rubyforge.org/projects/parsetree
目的
まず、「Rubyスクリプトを解析してなにがしたいのか?」を説明しておきますね。
実装済みのRubyのクラスのクラスメソッドやインスタンスメソッドのテスト(RSpec)のひな形を自動生成したいと思っています。(できるかどうかはおいといてね。)
例えば、次のようなFooクラスがあるとします。(im、cmは、それぞれinstance methodとclass methodの略です。)
class Foo def im1(arg) if arg return arg else return nil end end def self.cm1(arg1, arg2) case arg1 when "a" return arg2 when "A" return arg2.upcase else return nil end end end
そこから次のようなテストを自動生成したいのです。
describe Foo do describe "#im1" do context "if arg" do # TODO: # return arg end context "else" do # TODO: # return nil end end describe ".cm1" do context 'arg1 === "a"' do # TODO: # return arg2 end context 'arg1 === "A"' do # TODO: # return arg2.upcase end context "else" do # TODO: # return nil end end end
ripperとruby_parserのどちらを使うのか?
さて、目的がはっきりしたので、あとはやるだけですwww
私は、ripperとruby_parserの両方共使ったことがないため、そもそも何ができるのかを調べるところからです。
ripperは、るりま (http://doc.ruby-lang.org/ja/2.0.0/library/ripper.html) がちょー詳しいです。感謝感謝。
Ripper::Filter (http://doc.ruby-lang.org/ja/2.0.0/class/Ripper=3a=3aFilter.html) を使って、ちょちょっとやれば解析できそうです。
ruby_parserはripperよりももっと簡単です。以下のようなコードでRubyスクリプトを解析して、プログラムから扱いやすい形(構文木)に変換してくれます。
require "ruby_parser" result = RubyParser.new.parse(File.read("path/to/ruby_script")) ...
しかしながら、当たり前かもしれませんが、ripperもruby_parserもRubyスクリプトの構文解析まではしてくれますが、意味までは教えてくれません。つまり、「ifがあるよ、ifの近くにargがあるよ、ifの中にreturnがあるよ、returnの近くにnilがあるよ」みたいなことは教えてくれるのですが、argがifの条件だとか、nilを返すとかの作りこみが必要なのです。
あと、ruby_parserは簡単に構文木にできるのですが、行番号は取れません。これだと困りそうなので、ripperを使うのかな〜と思ったり...
なにわともあれ、まだ調査を始めたばかりです。ゴールまでの道のりはまだまだ遠い...
(つづく...)
--- PR広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。
- かくってる?: http://cocktailq.herokuapp.com/