6

クラス「製品」に含めたい「電卓」を呼び出すモジュールがあります。Calculator は、クラス メソッドを Product にコピーする "Product" を拡張します。これらのクラス メソッドの 1 つが「memoize」です。私はこのようなことができるという考えです:

module Calculator
  def self.extended(base)
    base.memoize :foo_bar
  end
end

メソッド (具体的にはクラス メソッド) :foo_bar をメモ化する目的で。memoize の内部で、クラス メソッドを別の名前 (ここでは :foo_bar) にエイリアスしようとする "alias_method" メソッドを呼び出します。これは失敗します。メモ化は次のようになります。

module Calculator (the extended module)
  def memoize(name)
    alias_method "memoized_#{name}", name
  end
end

これが memoize :foo_bar を介して呼び出されると、alias_method の行で Product has no method "name" というエラーが表示されます。しかし、大したことはありません)..

私はそのように固有クラスを再開することができます

module Calculator
  def memoize(name)
    class << self
      alias_method "memoized_#{name}", name
    end
   end
end

これは機能しますが、 name は class << self 定義のスコープでは使用できません。人々は self.class_eval と self.instance_eval の使用について言及しましたが、どちらも機能していないようです..ケーキが欲しいので、それも食べたいです..どうすれば alias_method を動的に保ちながら class_methods で使用できますか?

4

2 に答える 2

3

したがって、これでうまくいくことがわかりました:

module Calculator
  def memoize
    define_singleton_method(name, method(name))
  end
end

次に、Calculator が Product に組み込まれると、必要に応じて singleton メソッドが定義されます。なぜalias_methodがインスタンスメソッドでのみ機能する必要があるのか​​\u200b\u200bまだわかりません..そして、なぜclass_evalまたはinstance_evalが問題を解決しなかったのかわかりません..しかし、少なくとも私には解決策があります..

于 2012-11-15T23:48:45.440 に答える
3

インクルード/エクステンドの前にエイリアス化するインスタンス メソッドを配置するとどうなりますか? クラス名の直後にextendを置くと、インスタンスメソッドはまだ定義されていません。

module Foo
  def self.extended(base)
    base.memoize :flavor
  end

  def memoize(name)
    alias_method "memoized_#{name}", name
  end
end

class Bar
  def flavor
    puts "Orange"
  end

  extend Foo
end

if __FILE__==$0
  b = Bar.new
  b.memoized_flavor   #=> Orange
end
于 2012-11-16T06:05:25.957 に答える