しばらくGemを作ってなかったので気がつかなかったのですが、 Gem作りを取り巻く環境が結構変わっているようですね。

まず、newgemやcutagem, hoeのようにgemのひな形を作ってくれる jeweler というtoolが結構使われているようです。これはgithubにインテグレートされていて非常に便利です。

githubはちょっと前からgemをホストするgemリポジトリサービスをやめてしまったようで、代わりに Gemcutterを使うようになっています。 jewelerを使う事で、gemcutterやrubyforgeにgemをpushする事ができます。

posted by Png genki on Sat 17 Oct 2009 at 10:20

たまにRubyforgeが落ちていてgem installする事ができなくなっている場合がありますが、そんな場合には以下のミラーサーバが利用できるかもしれません。

ローカルにダウンロードしてから sudo gem install します。

posted by Png genki on Sat 10 Oct 2009 at 20:03

GAEなどでファイル数の多いライブラリを使うために、gemのパッケージから不要そうなファイルを消してjarファイルにまとめるために作ったスクリプトです。

   1  #!/usr/bin/env ruby
   2  
   3  def run(command)
   4    puts command
   5    system command
   6  end
   7  
   8  case ARGV[0]
   9  when 'install'
  10    run "jgem install -i ./gems --no-ri --no-rdoc #{ARGV[1]}"
  11  when 'uninstall'
  12    run "jgem uninstall -i ./gems #{ARGV[1]}"
  13  end
  14  
  15  Dir['gems/gems/*'].each do |dir|
  16    %w(
  17      Generaters TODO README.* README
  18      spec/**/* test/**/* examples/**/* tasks/**/*
  19      tutorial/**/* demo/**/* website/**/*
  20      CHANGES CHANGES.txt CHANGELOG
  21      LICENSE MIT-LICENSE Rakefile CONTRIBUTORS
  22      Manifest.txt History.txt install.rb setup.rb
  23    ).each do |pattern|
  24      Dir[File.join(dir, pattern)].each do |path|
  25        run "rm -rf #{path}"
  26      end
  27    end
  28  end
  29  
  30  Dir['gems/cache', 'gems/bin', 'gems/doc'].each do |path|
  31    run "rm -rf #{path}"
  32  end
  33  
  34  run "jar cf lib/merb.jar -C ./gems ."

posted by Png genki on Mon 7 Sep 2009 at 19:16 with 2 comments

Gemを作るのが面倒になってきたので、githubから直接requireできたら楽になるかもしれないと思い、試してみました。

   1  def git(uri, sha1, options = {})
   2    require "tmpdir"
   3    basename = File.basename(uri)
   4    outdir = File.join(Dir.tmpdir, basename, sha1)
   5    unless File.exist?(outdir)
   6      sh = proc{|command| IO.popen("#{command} 2>&1"){|io| io.read}}
   7      sh["git clone #{uri} #{outdir}"]
   8      sh["cd #{outdir}; git checkout #{sha1}"]
   9    end
  10    $:.unshift File.join(outdir, 'lib')
  11    require options[:require_as] || basename.split(/\.git$/)[0]
  12  end

Dir.tmpdirを使ってOSのテンポラリディレクトリの下にリポジトリをクローンしてきて、指定したリビジョンをcheckoutし、LOAD_PATHに"lib"を加えて、リポジトリ名のファイルをrequireしています。

意外と普通にgemの代わりに使える感じです。

posted by Png genki on Thu 16 Jul 2009 at 17:40

RubyGemsを使うときに、たびたびGemのバージョンを指定する機会があります。 '=', '>=', '>' などの等号、不等号は、対応するRubyのオペレータと同じような機能なのでわかりやすいのですが、'~>'についてはどういう意味なのか若干わかりにくい感じです。一応マニュアルにはこんな感じに書かれています。

  • = Equals version
  • != Not equal to version
  • > Greater than version
  • < Less than version
  • >= Greater than or equal to
  • <= Less than or equal to
  • ~> Approximately greater than (see "Pessimistic Version Constraint" below)

'~>' は、悲観的(pessimistic)なバージョン指定です。 例えば、'~> 1.2.0' は、'1.2.0', '1.2.1.1' などにはマッチしますが、 '1.3'にはマッチしません。 最後の数字の桁だけがGrater than or equal toで、それ以外は厳密一致のようです。

posted by Png genki on Sat 6 Jun 2009 at 02:04

GAEを使う上での大きな制限として、ファイル数1000までというのがあります。 これを乗り越えるために、unpackしたGemの中から不要なファイルを掃除したりする必要があったのですが、 関連するGem群をjarファイルにまとめる事でこの問題を乗り越えられます。

上記のファイルをlibの下に配置して、config/init.rb あたりでrequire_fixを読み込みます。 これはjarファイルの中のrbファイルの読み込みに関するバグを 回避するためのものです。

実際に以下のサイトでmerb.jarを使って運用しています。

これによって、事実上ファイル数制限に左右されずにアプリケーションを開発する事が出来るようになります。 ただ、1ファイルのサイズ制限(10MB)が存在するので、jarファイルが大きくなりすぎた場合は分割する必要があります。

posted by Png genki on Sun 19 Apr 2009 at 08:46

GAE/Jにはファイル数制限(1000まで)があるので、なるべく不要なファイルは減らしたいのが人情というものです。 ということで、unpackしたgemsから不要なファイルを掃除するために、以下のようなスクリプトを使用しています。

script/strip_gems

   1  #!/usr/bin/env ruby
   2    
   3  Dir['gems/gems/*'].each do |dir|
   4    %w(
   5      Generaters TODO README.* README
   6      spec/**/* test/**/* examples/**/* tasks/**/*
   7      tutorial/**/* demo/**/*
   8      CHANGES CHANGES.txt CHANGELOG
   9      LICENSE MIT-LICENSE Rakefile CONTRIBUTORS
  10      Manifest.txt History.txt install.rb setup.rb
  11    ).each do |pattern|
  12      Dir[File.join(dir, pattern)].each do |path|
  13        command = "rm -rf #{path}"
  14        puts command 
  15        system command
  16      end
  17    end
  18  end

Gemの中に含まれているファイルには制約が無いので、 簡単なパターンで全てを掃除するのは難しいですね。

posted by Png genki on Wed 15 Apr 2009 at 04:54

非常にシンプルなのですが、毎回GlobalHelpersに書くのが面倒なので、 Merbから GRAVATAR のアイコンを表示するための merb_gravatarプラグインを作りました。

http://github.com/genki/merb_gravatar/tree/master

インストール方法

   1  % sudo gem install merb_gravatar

使用法

dependencyでmerb_gravatarを指定して、viewで以下のように使います。

   1  <%= gravatar @user.mail, 16 %>

第二引数はアイコンのサイズを1~80で指定します。省略すると80が選ばれます。

ss1

GAE/Jでも使えます(See http://watch-me.appspot.com/people)

posted by Png genki on Tue 14 Apr 2009 at 11:11

gemを指定したディレクトリにインストールする方法を紹介します。 以下のように -i オプションでディレクトリを指定します。

   1  gem install -i ./gems data_objects --no-ri --no-rdoc

Gemをunpackしている場合に、もう一つ、二つGemを追加したい時などに重宝します。

posted by Png genki on Sun 12 Apr 2009 at 17:36 with 2 comments

GAEjのファイル数制限が厳しいので、rails.jarを試作してみました。

rails-2.3.2.jar

jrubyのバグなのか、jarファイルの中身に対してrequireをする時に、 pathの中に../..のような感じの指定が入っているとうまくロードできないようなので、その問題を回避するモンキーパッチをあてる必要がありました。

require_fix.rb

   1  alias :require_original :require
   2  def require(path)
   3    path = File.expand_path(path) if path.to_s.match(/^file:/)
   4    require_original path
   5  end
   6  
   7  alias :load_original :load
   8  def load(path)
   9    path = File.expand_path(path) if path.to_s.match(/^file:/)
  10    load_original path
  11  end      

それでこんな感じに使えます。

   1  % java -jar $JRUBY_HOME/lib/jruby-complete.jar -rrequire_fix -rrails-2.3.2.jar -S rails -v
   2  Rails 2.3.2

実際にはlibの下に設置する感じになりますね。

posted by Png genki on Sat 11 Apr 2009 at 19:34