既存のRubyのクラスの、テストコードgeneratorを作成する(1)

ちょっと機会があって、プログラムでRubyスクリプトを解析したいと思って調べています。まだまだ調査中なので中途半端な情報になってしまいますが、ご勘弁ください。
Rubyソースコードを解析するためのソフトウェアとしては、Ruby標準添付のripperと、seatle.rb (http://www.seattlerb.org/) のruby_parserが有名ですので、それらを使うことを前提に調査しています。

目的

まず、「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広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。

今日のブックマーク

すみません、今日は気になった記事の列挙だけです。

[ソフトウェア]Command Line で使用しているツールまとめ vol.3

tmuxなど
http://qiita.com/items/bd319bdaffb403d5e605

[Ruby][Rails]Railsで、FactoryGirlの全factoryを自動でテストする

http://beyond.cocolog-nifty.com/akutoku/2013/04/railsfactorygir.html

[Emacs][Git]gitのブランチ名を表示する

http://d.hatena.ne.jp/hico_horiuchi/20130510/1368201907

GitHubのprivateレポジトリを取り巻く、エコシステム

GitHubのprivateレポジトリを取り巻く

少し興味があって、GitHubのprivateレポジトリの料金や、privateレポジトリに関連したサービス(ここでは、エコシステムと呼んでみましたw)を調べてみました。

ソースコード管理: GitHub - https://github.com/

説明は不要かもしれませんが、GitHubは、ソースコードを管理するためのサービスですね。オープンソースソフトウェア、つまりソフトウェアのソースコードを公開する場合は無料で使えます。特定企業向けのソフトウェアなどのように、ソースコードを非公開しないといけない場合は、毎月$9からのプランがあります。企業向けのプランは、毎月$25といったところでしょうかね。(料金の詳細は https://github.com/plans にあります)

CI: CircleCI - https://circleci.com/

CircleCIは、ソフトウェアのテストを定期的に行うためのサービスです。(実際にはテストだけでなく、ソフトウェアの変更があったときに行いたいことであれば、設定次第でいろいろできるすぐれものです)
一度作った機能が常に正しく動作することを保証するために使います。ソフトウェアにとっては、重要なことですね。
これは、毎月$19かかります。(料金の詳細は https://circleci.com/pricing にあります)

コードカバレッジ測定: COVERALL - https://coveralls.io/

CIで実行するテストが、ソースコードのどの箇所を通っており、また、どこを通っていないかを測定することを「コードカバレッジ測定」といいます。これを定期的に行なってくれるサービスがCOVERALLです。
これは、毎月$4.99かかります。(料金の詳細は https://coveralls.io/pricing にあります)

三種の神器: GitHub + CI + COVERALL

ここまで説明したGitHub、CircleCI、COVERALLはソフトウェア開発の三種の神器といっていいでしょうwww
毎月$50の費用がかかってしまいますが、これらを使えば、かなり強固なソフトウェアを開発できるでしょう。逆に言うと、これら、またはそれと同程度の環境がなければ、開発者自身がそれを自分で行う必要があり、余計な手間が発生する可能性があるでしょう。せっかくなので、その余計な手間がどれくらいなのか検討してみました。
自分で三種の神器と同等のシステムを構築する場合、私の経験だとそのメンテナンス(定期的なアップデートや障害対応)に毎月1日(8時間)程度の時間が必要になるでしょう。
もし三種の神器と同じ事を、システムを導入せずに開発者が手作業でやっていた場合は、毎月3日(24時間)程度の時間が必要になるでしょう。
つまり、渡しの場合は$50と1日分の手間賃を比較すればいいわけですねwww
みなさんにとって、毎月$50はどう映ったでしょうかね?安かった?高かった?

(えっと、三種の神器以外のサービスは、時間があるときにまた説明しますねwww)

--- 参考情報

--- PR広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。

Rails本体の、generatorのgeneratorを変更したい!!

最近、Railsのカスタムgeneratorが銀の弾丸(開発効率を飛躍的に上げるもの)にならないかと思っていろいろ試しています。いまのところ、成果は上げっていませんwww駄菓子菓子(だがしかし)、generatorを作成することに対する敷居がとても下がりました。まだ、Railsのカスタムgeneratorを作ったことがない方は こちらの記事(http://d.hatena.ne.jp/kouji0625/20130523/p1) を参考にして作ってみてくださいね。
さて、ここからが本題です。

今回のお題

Rails本体のgeneratorのgeneratorを変更したい!!
ややこしいな。つまり、「rails generate generator foo」で生成されるUSAGE、foo_generator.rbを修正したいってことです。

手順

まずは、Ralis本体からgeneratorのテンプレートをコピーします。

$ mkdir -p lib/templates/rails/generator
$ cp -r ~/.rvm/gems/<ruby_version>@<gemset>/gems/railties-<version>/lib/rails/generators/rails/generator/templates/* lib/templates/rails/generator

あとは、lib/templates/rails/generator以下のファイルを修正するだけです。
すると、rails generate generator fooで自動生成されるファイルが、上記のコピーしたファイルを元にしたものになります。
簡単ですね♪

おまけ

ammeterを使っていれば(http://d.hatena.ne.jp/kouji0625/20130524/p1)、以下の内容のファイルをspec/generators/rails/generator/generator_generator_spec.rbに配置することで、カスタマイズしたGeneratorGeneratorのspecが書けます。generatorのspecがあれば、Railsをバージョンアップしたときに、いちいちrails generateを実行して動作確認しなくてもいいというのがうれしいですね。

require 'spec_helper.rb'

require "rails/generators/rails/generator/generator_generator"

describe Rails::Generators::GeneratorGenerator do
  destination_root = File.expand_path("tmp/spec/generators", Rails.root)

  before do
    Rails::Generators::GeneratorGenerator.instance_eval do
      source_root File.expand_path('lib/templates/rails/generator', Rails.root)
    end
    run_generator %w(foo)
  end

  describe "lib/generators/foo/foo_generator.rb" do
    subject { file("lib/generators/foo/foo_generator.rb") }
    
    it { should exist }
  end
end

--- 参考情報

--- PR広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。

Railsのカスタムgeneratorの、グループ分けをする

今回のお題

Railsのカスタムgeneratorは、以下のように「Rails」「Rspec」といったグループに分けられています。このグループ分けはどのようにするのでしょうか?

$ rails generate
--- 以下、実行結果 ---
Usage: rails generate GENERATOR [args] [options]

General options:
  -h, [--help]     # Print generator's options and usage
  -p, [--pretend]  # Run but do not make any changes
  -f, [--force]    # Overwrite files that already exist
  -s, [--skip]     # Skip files that already exist
  -q, [--quiet]    # Suppress status output

Please choose a generator below.

Rails: <- ここ
  controller
  generator
  helper
  integration_test
  mailer
  migration
  model
  observer
  performance_test
  plugin
  resource
  scaffold
  scaffold_controller
  session_migration
  stylesheets

Initializer: <- ここ
  initializer

Rspec: <- ここ
  rspec:controller
  rspec:helper
  rspec:install
  rspec:integration
  rspec:mailer
  rspec:model
  rspec:observer
  rspec:scaffold
  rspec:view

試行錯誤

試しに、rails generate generatorで自動生成したgenerator(ここではrails generate generator initializerしたものを想定)を修正して、名前空間を分けてみましょう。

module AppName
  class InitializerGenerator < Rails::Generators::NamedBase
    (省略)
  end
end

すると、どうでしょう。rails generateとしても「Initializer:」すら表示されなくなりましたorz
単純に名前空間を分けただけではだめなんですね。
続いて、initializerディレクトリをapp_nameディレクトリ以下に移動してみましょう。つまり、以下のようなディレクトリ構成にします。

lib
`-- generators
    `-- app_name
        `-- initializer

今度は、rails generateで期待通りに表示されます。

(以下、rails generateの実行結果)
AppName:
  app_name:initializer

いいね。さっそく実行してみます。

$ rails generate app_name:initializer
Usage:
  rails generate initializer NAME [options]

Runtime options:
  -f, [--force]    # Overwrite files that already exist
  -p, [--pretend]  # Run but do not make any changes
  -q, [--quiet]    # Supress status output
  -s, [--skip]     # Skip files that already exist

Description:
    Explain the generator

Example:
    rails generate initializer Thing

    This will create:
        what/will/it/create

うんうん、いいですね。

まとめ

Railsのカスタムgeneratorのグループ分けは、

  • lib/generators/<グループ名>/に配置
  • <グループ名>名前空間にgeneratorを定義

といった手順でできます。

--- PR広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。

長生きはしたい、でも寝たきりでは...

社長からの紹介で、「全国民必読 慶應医学部が「長寿500人追跡調査」で解き明かした「100歳で元気ピンピンな人」の秘密: http://gendai.ismedia.jp/articles/-/35792」という記事を読みました。
簡単に説明すると、

  • 長寿の秘訣は糖尿病にならないこと
  • 糖尿病にならないためには食生活と適度な運動

というありがちなことが書いてある。
しかしながら、「ありがち」ではないことが書いてある。それは「アディポネクチン」という長寿の源だ。これを体内に増やすことで誰でも長寿になれる日がくるのかもしれない、といったような話まで書いてある。なかなかにおもしろい話だ。
そして、この記事の最後はこのようにしめている。

日本は世界一の長寿国だ。だがその反面、世界一寝たきり人口の多い国でもある。長寿ホルモン・アディポネクチンが、日本を本当の健康長寿国に導く未来は近いかもしれない。

長生きはしたいけど、好きな事もしていたい。アディポネクチンを増やす薬がない現代で、いまの私がそのような未来を描くためにはダイエットをせねばならん...

--- 参考情報

--- PR広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。

島根県松江市の、市民憲章を唱和して

ありがたいことに幼稚園のPTA会長も3期目となりました。ご存じない方もおられるかと思いますが、PTA会長とセットで地元の様々な役職に付くことになります。例えば、公民館運営委員会の委員です。
さてさて、地元の役職に付くと、さまざまな会に出席することにあります。その中で次のような市民憲章を、起立して、出席者全員で唱和することがありました。

一、 青い海と湖、緑あふれる美しい自然のめぐみを大切に、きれいなまちにします。
一、 人の立場を重んじ、すこやかで心にゆとりのある、明るく住みよいまちにします。
一、 礼をつくし勉学にいそしみ、未来にはばたく、希望にみちたまちにします。
一、 はるかな歴史のいとなみと、つちかわれた文化をうけつぎ、心ゆたかなまちにします。
一、 働くことによろこびと誇りをもち、活気がみなぎる、いきいきとしたまちにします。

なかなか、なんともいいことが書いてあります。ただ読むだけだと「ふーん」と気にもとめないのですが、みんなで声に出して読み上げてみると、それらしい気持ちになるものですね。お寺でお経をあげるのはこんな理由なのですかね(知らんけどw)。
なんか、PTAの会でも唱和してみようかなと思いました。

--- 参考情報

--- PR広告
記事を読んでくださり、ありがとうございます。もしよろしければ、この記事の著者が提供している無料のサービス「かくってる?」をお試しください。