kiyoka.2012_02_20 RSSPLAIN

Related pages: !kiyoka.blog.list !kiyoka.blog.2012_02
5543545555555555555555555555555555555555555555555555555555555555555555555555555555
5

[Ruby] nativeとpureの両方に対応したgemを作る方法

5

 

4

Sekkaの曖昧文字列マッチングを担っているkiyoka/fuzzy-string-matchEXTというgemのpure ruby版を作った話を書く。

3

JSONのgemがnativeとpureの両方をサポートしていたので参考したのだが、結果的にJSONよりもコンパクトに実現できたのでメモしておこう。

5

 

4

 

5

SekkaがJRubyでは動かないのでkiyoka/fuzzy-string-matchEXTのJRuby対応は自分は必要ないのだけど、GitHub上でJRuby用のforkが多かったので対応した。

5

自分はDebianパッケージ化の準備がメインの作業なのでgemの依存関係を直すだけでいいのだが、気分がノッている間に作業した。こういう勢いは重要だ。

5

DebianにはJRubyも入っているので、うまくいけばDebianのJRubyでも使えるのかな?

5

 

5

JRuby対応といってもJavaで高速な編集距離ライブラリをコーディングするわけではなく、pure Ruby版も用意しただけ。

5

GitHubでforkしてくれた方々はC言語に依存した部分を外してpure rubyのコードのみ残し、コメントに「JRubyで動かすため」と書いておられた。

5

処理速度もpure rubyで十分と書いておられる方もいた。

5

 

5

要望

5

JRubyでは、gccを必要とするRubyInlineをインストールしてほしくない。

5
fuzzy-string-match_pure パッケージはRubyInlineに依存せず、pure Ruby版のみがインストールされてほしい。
5
fuzzy-string-match と fuzzy-string-match_pure の二つのパッケージを両方同時にインストールしても良いようにしたい。
5
fuzzy-string-match は nativeとpureの両方を同梱してあり、テスト用に動的に切り替えれるようにしたい。
5

 

5

 

5

動的に切り替えるAPI

5

 

5
requireで切り替えれる
5

native版を使いたい場合

5
require 'fuzzystringmatch'
5
@jarow = FuzzyStringMatch::JaroWinkler.create()
5

 

5

pure版を使いたい場合

5
require 'fuzzystringmatch/pure'
5
@jarow = FuzzyStringMatch::JaroWinkler.create()
5

 

5
コンストラクタで切り替えれる
5

native版を使いたい場合

5
require 'fuzzystringmatch'
5
@jarow = FuzzyStringMatch::JaroWinkler.create( :native )
5

 

5

pure版を使いたい場合

5
require 'fuzzystringmatch'
5
@jarow = FuzzyStringMatch::JaroWinkler.create( :pure )
5

 

5

実装方法(Rubyコード)

5

native版にのみRubyInlineで実装したRubyクラスを含める。

5

require 'fuzzystringmatch' でrequireした時、native版のクラスが存在しなければ、自動的にpure版にfall backするようにした。

5

 

5

以下がLoadError例外処理を入れたrequire。JSONと同じ方法。

5

 

5
require 'fuzzystringmatch/pure'
5
begin
5
  require 'fuzzystringmatch/inline'
5
rescue LoadError
5
end
5

 

5

factoryメソッドで、実際にpure版にfall back しているコードがこちら。

5

native版のクラスのNameError例外を補足して、pure版のインスタンスを返している。

5

 

5
    def self.create( type = :pure )     # factory method
5
      case type
5
      when :pure
5
        FuzzyStringMatch::JaroWinklerPure.new
5
      when :native
5
        begin
5
          FuzzyStringMatch::JaroWinklerInline.new
5
        rescue NameError
5
          STDERR.puts "fuzzy-string-match Warning: native version is disabled. falled back to pure ruby version..."
5
          FuzzyStringMatch::JaroWinklerPure.new
5
        end
5
      end
5
    end
5

 

5

実装方法(gemspec)

5

fuzzy-string-match_pure gemパッケージは以下のようにしている。

5
RubyInlineへの依存を外している。
5
native版のRSpecテストケースを含めていない。
5
以下のファイルを含めない。
5
 lib/fuzzystringmatch/inline.rb
5
 lib/fuzzystringmatch/inline/*
5

それによって、factoryメソッドで :native が指定された場合でも、前述のRubyのLoadError例外によりpure版にfall backする。

5

 

5

このような方法で、純粋な計算しかしないライブラリではpure ruby版を用意すれば、それなりに喜ばれるだろう。

5

 

5

...comment disabled...