いけむランド

はてダからやってきました

Ruby でプラットフォーム毎に処理を切り分ける場合の定石ってあるの?

TwitterArchiveFilter を cygwin 上で動かす - すぱいだー日記。 を読んでいて、Ruby でプラットフォーム毎に処理を切り分ける場合の定石ってあるの?と思ったので、調べてみた。


先に libtidy.so が読み込まれると困るので、元のファイル名をリネームして回避されたとのことだが、そもそも scrAPI の .rb の書き方が良くないのではないかと思う。

いつも、自分が C で書かれたパッケージを cygport する時は cygwingcc に定義済みのマクロ __CYGWIN__ を使用して切り分けるわけだが、Ruby でも同様にプラットフォームの情報で切り分けるような書き方にすべきだと思う。

んで、調べてみたら、RUBY_PLATFORM にビルドの時に config.guess で取得した文字列が格納されているので、それを参照すればいいはず。


...みたいなことを書こうと思っていたら、既に本家で言及している人がいた。orz

Since the Scrapi gem ships with both a linux ".so" and a windows ".dll" the windows dll will never be found before the linux ".so" according to the strategy in "find_tidy()".

def find_tidy()
  return if Tidy.path
  begin
    Tidy.path = File.join(File.dirname(__FILE__), "../tidy", "libtidy.so")
  rescue LoadError
    begin
      Tidy.path = File.join(File.dirname(__FILE__), "../tidy", "libtidy.dll")
    rescue LoadError
      Tidy.path = File.join(File.dirname(__FILE__), "../tidy", "libtidy.dylib")
    end
  end
end

I suggest you use a platform detection mechanism like so:

  RUBY_PLATFORM =~ /mswin32/

And then the code will play more nicely. Otherwise, just stick to "require 'tidy'", atleast then Scrapi will only have the same problem that all the other gems do :)