2012-11-15 3 views
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"メソッドを呼び出します。これは失敗します。これはmemoize経由で呼び出され

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

:foo_barは、alias_methodラインはエラーと言って製品が何のメソッド「名前」..私の理解はこれがあるalias_methodは、インスタンスメソッドの別名しようとしているためであるがありません蹴るMemoizeは何かのように見えますクラスメソッド...(私はなぜけどOK大したことない知らない)。..

私はそう

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

ようeigenclassこれはうまくいく再度開くことができませんが、名前はの範囲に使用できません。クラス< <エルフの定義。人々はself.class_evalとself.instance_evalを使って言及しましたが、どちらもうまくいかないようです。私は自分のケーキを食べたいと思っています。どうすればalias_methodを動的に保つことができますか?class_methodsで使用できますか?

答えて

3

は、だから、これはトリックを行いますことを学んだ:

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

電卓は、製品に含まれますときに私は、必要に応じて、それはシングルトンメソッドを定義します。私はまだalias_methodがインスタンスメソッドでのみ動作する必要がある理由を知りません。なぜclass_evalまたはinstance_evalが問題を解決しなかったのかわかりませんが、少なくとも解決策はあります。

3

あなたはinclude/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 
+0

エイリアシングされる方法が実際に状況ではありませんでしたが、モジュール内で拡張され、試行されたエイリアシングの前に拡張されました。しかし、偉大な考え。 – Inc1982

関連する問題