Hpricot が Rails に勝手にロードされる不思議現象に遭遇し、今更知った fast_xs について。
- Rakefile で require 'tasks/rails'
- rails の tasks/rails で load 'tasks/misc.rake'
- misc.rake で require 'active_support'
- active_support で require 'active_support/core_ext'
- active_support/core_ext で require 'active_support/core_ext/string'
- active_support/core_ext/string で require 'active_support/core_ext/string/xchar'
- active_support/core_ext/string/xchar.rb で require 'fast_xs'
- なんか Hpricot がロードされとるよ…
環境は Rails 2.1.0, OSX10.5, MacPorts, RubyGems1.3 です。
fast_xs と Hpricot と RubyGems
$ find /opt/local/lib/ruby/gems/1.8/gems -type f -name "*fast_xs*"
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.161/ext/fast_xs/fast_xs.bundle
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.161/ext/fast_xs/fast_xs.c
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.161/ext/fast_xs/fast_xs.o
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.161/lib/universal-darwin9.0/fast_xs.bundle
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.164/ext/fast_xs/fast_xs.bundle
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.164/ext/fast_xs/fast_xs.c
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.164/ext/fast_xs/fast_xs.o
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.164/lib/universal-java1.6/fast_xs.bundle
確かに、Hpricot が fast_xs を同梱している様子。
$ ruby -rrubygems -e 'puts Gem.all_load_paths.select {|path| /hpricot/ =~ path }.join("\n")'
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6/lib/i686-linux
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6/lib
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.161/lib/universal-darwin9.0
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.161/lib
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.164/lib/universal-java1.6
/opt/local/lib/ruby/gems/1.8/gems/hpricot-0.6.164/lib
プラットフォーム(universal-darwin9.0)用のディレクトリもロードパスに含まれるんですね。
$ ruby -rrubygems -e 'p Gem.loaded_specs.has_key?("hpricot"); require "fast_xs"; p Gem.loaded_specs.has_key?("hpricot")'
false
true
require 'fast_xs' すると、Hpricot 同梱の fast_xs がヒットしてロードされ、その spec 名(?)は Hpricot だと。
$ ruby -rrubygems -e 'puts Gem.searcher.find("fast_xs").name'
hpricot
RubyGems の仕組みを追いかけきるのも一苦労なので、この辺で。
fast_xs
RubyForge から wget でダウンロードしたわけですが、異常に時間がかかりました。たまたまのトラブルでしょうか?
RubyForge: fast_xs: Project Info
以下、v0.7 の内容物。
- fast_xs-0.7/
- fast_xs-0.7/lib/
- fast_xs-0.7/lib/fast_xs_monkey_patcher.rb
- fast_xs-0.7/test/
- fast_xs-0.7/test/test_cgi_class_overrides.rb
- fast_xs-0.7/test/test_xml_escaping.rb
- fast_xs-0.7/test/test_erb_util_module_overrides.rb
- fast_xs-0.7/ext/
- fast_xs-0.7/ext/fast_xs/
- fast_xs-0.7/ext/fast_xs/extconf.rb
- fast_xs-0.7/ext/fast_xs/fast_xs.c
- fast_xs-0.7/ext/fast_xs/gcc.h
- fast_xs-0.7/ext/fast_xs/ruby_1_9_compat.h
- fast_xs-0.7/ext/fast_xs/fast_xs_type.h
- fast_xs-0.7/ext/fast_xs_extra/
- fast_xs-0.7/ext/fast_xs_extra/extconf.rb
- fast_xs-0.7/ext/fast_xs_extra/fast_xs_extra.c
- fast_xs-0.7/.gitignore
- fast_xs-0.7/README
- fast_xs-0.7/COPYING
- fast_xs-0.7/Rakefile
以下、README の引用。
= fast_xs, a fast C extension for cleaning XML
== Overview
The original fast_xs method is based on the xchar code by Sam Ruby:
http://intertwingly.net/stories/2005/09/28/xchar.rb
http://intertwingly.net/blog/2005/09/28/XML-Cleansing
_why also packages an older version with Hpricot (patch in progress).
It should be compatible with the latest version of this code.
This is an almost exact translation (to the best of my knowledge :) of
Sam's original implementation, but it does escape """.
XML::Builder as packaged in Rails 2.0 will be automatically use
fast_xs if available.
というわけで。
$ cd fast_xs-0.7
$ rake gem
$ sudo gem install pkg/fast_xs-0.7.19700101.090000.gem
$ ruby -rrubygems -e 'puts Gem.searcher.find("fast_xs").name'
fast_xs
fast_xs を hpricot としてアクティベーションさせたくなければ、fast_xs を fast_xs としてインストールしないと駄目ということですね。
まとめ
fast_xs としてインストールしておけば、Hpricot が勝手にアクティベートされて、バージョン縛りできない問題も解決。