ぴよログ

↓に移転したのでこっちは更新されません、多分。

アイデアカードとかいうツールをrubygem化

移転しました →

イデアカードとかいうアイデア出しのサポートツールを見つけました。

アイデアカード公式サイト

目的、着眼点、どう変えるかという3種類のカードがあってカードを引くことでランダムなフレーズが完成するってやつです。昔そういう遊びをしたことはありませんか?誰が、どこで、なにを、どうした、っていう感じたくさんカードにしておいてランダムに引いてできた文章がおかしくて笑う、みたいな遊び。それに近いです。

詳しく説明する気はあまりないので気になる人は上のURLを見てくれればおk。

実物のカードが存在するみたいなんですが、iOS版なんかもあるようです。じゃあRubyのプログラムにしちゃえばいいじゃん?ってことでgem化してみました。完成物はrubygems.orgにアップロード済みです。1回そこまでやってみたかったんです。

ソースはこちらです。

xoyip/idea_card

gemの作り方

こちらのスライドを参照しました。超助かりました。

  1. 最終的に必要になるのでrubygems.orgでユーザー登録。RubyGems.org | your community gem host
  2. $ bundle gem idea_card
  3. idea_card.gemspecを編集、authorとかemailとかを埋める
  4. 実装する
  5. $ rake install でローカルインストールして確認
  6. $ rake releaseする # 初回はrubygems.orgのIDとパスワードが設定されていないって怒られるので次の手順

  7. $ gem push

  8. IDとパスワードを入れる
  9. $ rake release

中身の説明

データファイル

カードには目的、着眼点、変化の3種類があります。それぞれの文言をハードコーディングしてもよかったのですが一応外部ファイルに書いておくことにしました。

一例ですが、目的を書いたgoalsというテキストファイルがあります。このように一行がカード一枚に対応しています。

スクリプト本体

こういう風に使えるように作りました。

IdeaCard.draw

IdeaCardはモジュールでdrawはモジュールの特異メソッドです。

で、実装はこれだけ。

ポイントはIdeaCard.goalIdeaCard.pointIdeaCard.changeの3つのメソッド。必要性はさておき、動的にメソッドを定義しています。実装がかぶっていたからメタにやってみようという程度の理由です。メソッドに対応したファイルを読んで入力を全て取っておき、そのなかからランダムに1つだけ返すという実装です。

微妙にはまる

これといって特に難しいことはありませんが、一箇所はまりました。

    current_file_path = File.dirname(__FILE__)
    functions.each do |m|
      eval <<-EOC
        def #{m}
          path = File.expand_path "./#{m}s", "#{current_file_path}" # <= この部分
          @#{m}s ||= load(path)
          @#{m}s.sample
        end
      EOC
    end 

このソースファイルと同じパスにデータファイルを置いてあるので、相対パスを使ってデータファイルを読みいくという作りにするつもりで、最初は"#{current_file_path}"のところにそのまま__FILE__としていました。ところが、evalするタイミングでは__FILE__はこのファイルをrequireしている人、つまりlib/idea_card.rb(一つ上の階層のファイル)になってしまっていました。おかげでデータファイルが取れないため想定したとおりに動きませんでした。

そういうわけで、evalの外で__FILE__の値を取っておくという上のような実装に変えて事なきを得ました。これってメタプロの仕組みちゃんとわかってれば当たり前なんですかね。

パーフェクトRubyメタプログラミングRuby読みなおそうかなー。

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

メタプログラミングRuby

メタプログラミングRuby