2012-01-18 29 views
11

私はこの質問(How to do attr_accessor_with_default in ruby?)が私の質問に答えたと思っていましたが、私はActiveRecordを使用しておらず、after_initializeはそれに依存しています。ActiveRecordのないプロパティにデフォルト値を設定する最も良い方法は?

attr_accessorのデフォルト値を実装するためのRubyベストプラクティスは何ですか? thisはドキュメントに関する最も近いものですか? attr_accessorはプライベートなので使用を中止する必要がありますか?

+0

あなたが理由を知っていることが分かっていない限り、あなたは '@@'変数を望んでいません。クラスレベルのインスタンス変数(下の私の答えを参照)は、より多くの仕事をしてくれますが、サブクラスに関してはあまり驚くことはありません。あなたは本当に何を達成しようとしていますか? – Phrogz

+0

私は今何が起こっているのか見て、私は編集を削除するつもりです。私はattr_accessorがRailsのものであると誤解していました。 – jcollum

答えて

20
class Foo 
    # class-level instance variable 

    # setting initial value (optional) 
    @class_var = 42 

    # making getter/setter methods on the class itself 
    class << self 
    attr_accessor :class_var 
    end 

    # instance-level variable getter/setter methods 
    attr_accessor :inst_var 
    def initialize 
    # setting initial value (optional) 
    @inst_var = 17 
    end 
end 

p Foo.class_var 
#=> 42 
Foo.class_var = 99 
p Foo.class_var 
#=> 99 

f1 = Foo.new 
f2 = Foo.new 
f2.inst_var = 1 
p [f1.inst_var, f2.inst_var] 
#=> [17,1] 
+2

優秀な答え、ありがとう。 'attr_accessor'はプライベートではどうでしょうか? Rubyが私のような非公開のものを使うことができるのは、C#の特有のものです。それは単なるプライドのようなものです。奇妙な – jcollum

+0

プライベートメソッドを作成するのではなく、プライベートメソッドです。クラスを開いたときにのみ使用されることを意図しています。後でいつでもクラスを再オープンすることも、 'Foo.instance_eval {attar_accessor:bar}'を実行することも、 '' __send__'(http://www.ruby-doc.org/core-1.9.3/BasicObject)を使うこともできます。 html#method-i -__ send __)、制限をバイパスします。はい、あなたが欲しいのなら、Rubyはあなたに鋭いナイフを与えます。 – Phrogz

+0

うーん、まさに私が必要とするものではない。私は '@debugが= falseを クラス<<自己 attr_accessor行うと: end'をデバッグし、そのクラスを継承するクラスのインスタンスを作成し、デバッグプロパティはnilです。私はデフォルト値を持っているので、そこに「偽」があると思います。ねじれた書式設定には申し訳ありません。 – jcollum

1

@Phrogzはすばらしい解決策を示しましたが、詳細は知っておく必要があります。

ここでは、実際にクラス変数ではありませんが、同じ名前の実クラス変数を初期化すると古い参照が失われるため、誰が気にしますか?class-level instance variableを作成します。

は、fakenessを検査し、上記のコードを使用し、それに配列を持つ:

class Foo 
    @class_var = [42] 
    class << self 
    attr_accessor :class_var 
    end 
end 
b = [Foo.class_var] 
Foo.class_var = 69 
p b # still [[42]] 

そして、あなたが問題を得ようとしている、実際のクラスになっていた@@を介して可変を取得しようとしたとき変数。

class Bar 
    @class_var = [42] 
    class << self 
    attr_accessor :class_var 
    end 
    def biz 
    self.class.class_var 
    end 
    def baz 
    @@class_var 
    end 
end 
p Bar.new.biz # self.class. is kinda a way to emulate the reference from outside 
p Bar.new.baz # and exception, because you don't really have a class variable defined yet!