ActiveSupportのXMLパーサの実装をLibXMLに変更できない件

 ActiveResourceが使うXMLパーサの切り替えWindowsにlibxml-rubyインストールの続きです。Railsアプリのconfig\environment.rbに設定情報を記述することで、ActiveSupportXMLパーサの実装をLibXMLに切り替えられないかと考えています。(先日の日記では、ActiveResourceXMLパーサとしていましたが、ActiveResourceActiveSupportXMLパーサを参照しているようです。)
 いろいろ試してみましたが、だめでした。ご存知の方、いないでしょうか。
 とりあえず、やったことをメモします。

environment.rbの設定

 environment.rbをこんな感じにすればできるかなと思いました。でも、サーバを起動すると、エラー終了してしまいます。

Rails::Initializer.run do |config|
            
          #中略

  config.active_support["XmlMini.backend"] = 'LibXML'
end

そのときに、コマンドプロンプトに出力されたメッセージです。メソッドがないとのこと。

c:/ruby/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:584:in `send': und
efined method `XmlMini.backend=' for ActiveSupport:Module (NoMethodError)

トレース

 ソースをトレースしてみます。トレースしてみて、上に書いたような感じでうまくいくんじゃないかと思った次第です。
 まず、environment.rbでは、Rails::Initializer.runを呼び出しています。(1)、(2)、(3)の順に説明していきます。

C:\ruby\lib\ruby\gems\1.8\gems\rails-2.3.2\lib\initializer.rb

    def self.run(command = :process, configuration = Configuration.new)  # (1)
      yield configuration if block_given?  # (2)
      initializer = new configuration
      initializer.send(command)  # (3)
      initializer
    end
(1) configuration = Configuration.new

 Rails::Initializer.runは、引数なしで呼び出されているので、デフォルトで、Configurationをnewしています。
 initializer.rbの下の方へ行くと、Configurationのコンストラクタが定義されています。Rails::OrderedOptionsを生成し、active_supportに代入しています。

    # Create a new Configuration instance, initialized with the default
    # values.
    def initialize
      
         中略

      self.active_support = Rails::OrderedOptions.new
    end

 initializer.rbのさらに下の方へ行くと、Rails::OrderedOptionsクラスが定義されています。これは、key-valueストアですね。

# Needs to be duplicated from Active Support since its needed before Active
# Support is available. Here both Options and Hash are namespaced to prevent
# conflicts with other implementations AND with the classes residing in Active Support.
class Rails::OrderedOptions < Array #:nodoc:
  def []=(key, value)
    key = key.to_sym

    if pair = find_pair(key)
      pair.pop
      pair << value
    else
      self << [key, value]
    end
  end

  def [](key)
    pair = find_pair(key.to_sym)
    pair ? pair.last : nil
  end

  def method_missing(name, *args)
    if name.to_s =~ /(.*)=$/
      self[$1.to_sym] = args.first
    else
      self[name]
    end
  end

  private
    def find_pair(key)
      self.each { |i| return i if i.first == key }
      return false
    end
end

 ここまでで、config.active_support変数は、空の配列(keyとvalueのペアを要素とする)として初期化されることがわかりました。

(2) yield configuration if block_given?

 ここで、environment.rbの"Rails::Initializer.run do |config| end"ブロックが実行されます。ブロック内に記述した、

config.active_support["XmlMini.backend"] = 'LibXML'

が呼び出されます。Rails::OrderedOptionsの[]=(key, value)が呼び出され、("XmlMini.backend", 'LibXML')が(key,value)として登録されます。

(3) initializer.send(command)

 commandのデフォルトは:processなので、processメソッドが呼び出されます。processメソッドで、initialize_framework_settingsが呼び出されています。

    # Sequentially step through all of the available initialization routines,
    # in order (view execution order in source).
    def process

                中略

      initialize_framework_settings

        中略
    end

 initialize_framework_settingsでは、ActiveSupportの"#{setting}="メソッドを呼び出します。ここで、settingとは、先ほど説明したkey-valueのkeyに対応します。
C:\ruby\lib\ruby\gems\1.8\gems\rails-2.3.2\lib\initializer.rb

    # Initializes framework-specific settings for each of the loaded frameworks
    # (Configuration#frameworks). The available settings map to the accessors
    # on each of the corresponding Base classes.
    def initialize_framework_settings
      configuration.frameworks.each do |framework|
        base_class = framework.to_s.camelize.constantize.const_get("Base")

        configuration.send(framework).each do |setting, value|
          base_class.send("#{setting}=", value)
        end
      end
      configuration.active_support.each do |setting, value|
        ActiveSupport.send("#{setting}=", value)
      end
    end

 これを利用して、ActiveSupportモジュール内で、XmlMini.backend = 'LibXML'を呼び出そうと目論んでいました。

トレースしてみて、

 keyとしてメソッド名だけじゃなく、モジュール名"XmlMini"まで入れていることが問題かなとも思います。単にrubyを知らないだけかも。。