0

method_missingボキャブラリで名前空間定数のクラスを定義するために使用しています。効果的にするには、語彙クラスを から継承する必要がありますBasicObject。そうしないと、語彙用語として標準オブジェクト メソッドを使用できません (メソッドが欠落していないためです :)。ただし、から継承するとBasicObject、別のモジュールでユーティリティ メソッドを呼び出すことができないことがわかります。次のコードは、要約された形式で問題を示しています。

module Foo
  class Bar
    def self.fubar( s )
      "#{s} has been fubar'd"
    end
  end
end

class V1
  def self.method_missing( name )
    Foo::Bar.fubar( "#{name} in v1" )
  end
end

class V2 < BasicObject
  def self.method_missing( name )
    Foo::Bar.fubar( "#{name} in v2" )
  end
end

# this works
puts V1.xyz
# => xyz in v1 has been fubar'd

# this doesn't
puts V2.xyz
# => NameError: uninitialized constant V2::Foo

V2ヘルパー モジュールを呼び出そうとしたときに、初期化された定数エラーが発生しないようにするには、何を追加する必要がありますか?

4

1 に答える 1

3

V2名前解決がグローバルスコープで開始されるように、このようにメソッドを変更すると機能します。

def self.method_missing( name )
  ::Foo::Bar.fubar( "#{name} in v2" )
end

私はあなたのためのドキュメントでそれを調べました:

BasicObject には Kernel (puts などのメソッド用) は含まれず、BasicObject は標準ライブラリの名前空間の外にあるため、完全なクラス パスを使用しないと共通のクラスは見つかりません。... Ruby 標準ライブラリからのクラスとモジュールへのアクセスは、::File や ::Enumerator のようにルートから目的の定数を参照することで、BasicObject サブクラスで取得できます。

于 2012-06-13T11:00:09.383 に答える