2009-08-13 12 views
3

私は、class variables are bad in Rubyという記事を見てきました。彼らは、メタクラス(またはシングルトンクラス)の使用を提案しています。これは私がfoo2はとattr_accesor使用する方法はありませんけれどもfooとfoo2はは、基本的に同じであることを理解し、私のサンプルコードRuby:メタクラスとクラス変数

class Joe 
    class << self # here we're putting methods in Joe's "meta class" 
    attr_accessor :foo 
    end 
    def self.foo2 
    end 
    def self.foo2=value 
    end 
end 

puts Joe.singleton_methods 

です。

私はclass << self syntaxの内容を知りません。何らかの連結が起こっているのですか、それとも何ですか?拡張、継承、猿パッチのようなものですか?

編集(ボーナス):私がここにいる間、ビューヘルパーにデータをキャッシュする方法はありますか?私はこのクラスを使用しようとしました< <自己のものですが、ヘルパーメソッドはアクセサを見つけることができません。

+0

はちょうど私がヘルパークラスVARSにその値をキャッシュするために取得するには、クラスのキャッシングを遮断しなければならないことに気づきました。私が思ったより簡単だった。 –

答えて

10

class<< foo構文は "FOOのクラスの定義で" の略です。あなたがこれを行うのであれば:

class Foo 
    class << self 
    # class method defined as INSTANCE method 
    # the only instance being Foo (the class) 
    def boo 
     ... 
    end 
    end 
end 

これは、同じ静脈で

class Foo 
    def self.boo #class method 
    end 
end 

に似ている、あなたは別のオブジェクトを取得し、

class << some_object 
    def something # adds a method to some_object ONLY 
    end 
end 

だから、方法でそれを拡張することができたときにあなたをクラス定義内で "selfのクラス"を実行すると、コンテキスト内のものを呼び出すことができる "固有クラス"(または "メタクラス")の定義に "1レベル上に" をジャンプしています。あなたの "クラスのインスタンスの私は"この中にいる。そのため、クラスメソッド はインスタンスメソッドになり、そのように定義されて処理され、 モジュールがクラスメソッドに影響を与えます。あなたのケースでは

class Joe 
    # here we're putting methods in the "class of class" 
    class << self 
    include ClassMethodsForJoe 
    attr_accessor :foo 
    end 
end 
Joe.foo # this is the method we made 
+0

それをチェックアウトしますありがとうございました。それは私が必要とする答えです。 –

+0

良い答え。あなたは ""クラス "foo"は "fooのクラスの定義"の略です。 @ sepp2kは答えました。「クラス<< foo'はfooのシングルトンクラスを開きます...」(しばしば見られる式)。これらの両方は私には少し曖昧に思える。 「クラス<< fooはfooのシングルトンクラスと同じに設定されています」と言うのは正確ですか? –

+0

"eigenclass"や "singleton class"があなたのことを知ったら、このような質問をしないので、私はやったことがあります。私は、これらの概念の両方がRubyで意味するものを既に知っている人にとって有益であることを発見しました - そして、クラス全体のクラス構造を説明するのに役立たないことがわかりました。 – Julik

6

class << fooはfooのシングルトンクラスを開きます。これは、fooが唯一のインスタンスである(fooの "実際の"クラスを暗黙的に継承する)クラスです。つまり、ある種の拡張です(特定のオブジェクトにそのオブジェクトのクラスで定義されていないメソッドを追加しています)。あなたがそのオブジェクトにのみ影響を与え、そのクラスの他のオブジェクトには影響しないので、これはサルのパッチ適用ではありません。 def foo.barは単に

class <<foo 
    def bar 

すなわち、それは舞台裏で同じことをするための近道であることを

注意。 <<は、<<メソッドとは関係ありません。それは構文の一部です。

+0

クール、ありがとうございます。私は、ビューヘルパーでこれを使用することができますどのように...(実際には別の質問で再び自分自身を説明していないため)ボーナスで質問を編集しました。 –

1

ビューヘルパーでデータをキャッシュする場合、memoizationを使用できます。

+0

私は今それを得る。しかし、もっと重要なのは、私は設定でキャッシングを止める必要があるということです。優れた –

関連する問題