2012-03-03 21 views
6

Rubyのインスタンス変数を理解しようとすると少し狂っていると思います。私の唯一の目的は、与えられたクラスに対して作成されたすべてのオブジェクトに、の変数があり、そのクラスに対してinitializeメソッドを書き込まないで、メソッドを書き込むことです。ような何か:Rubyのインスタンス変数の初期化

class Test 

    @my = [] 

    attr_accessor :my 

end 
t = Test.new 
t.my # I want [] but this shows nil 

はそれがinitializeに触れることなく、これを達成することは可能ですか?ありがとう。

EDIT:は明確にするために、私は、それが実行されているクラスにインスタンス変数を追加しますという意味でattr_accessorと同様に実行されるコードのいくつかの作品を書いています。私が自分でinitializeを書くと、私はユーザーが書いたものを壊してしまいます。

答えて

11

あなたがやっていることは、クラスレベルでインスタンス変数を定義することです(クラスはClassクラスのインスタンスなので、これはうまくいきます)。

いいえ、初期化する方法はありません。

編集:あなたの編集には少し誤解があります。 attr_accessorはインスタンス変数をクラスに追加しません。それは何、文字通り、これは(myのあなたの例を使用して)です:

def my; @my; end 
def my=(value); @my = value; end 

それは積極的に作成/任意のインスタンス変数を初期化し、それだけで2つのメソッドを定義しません。を使って同様のことをする独自のクラスメソッドを作成することもできます。

編集2:

さらに、1つは、このような方法を記述します方法を示すために:

class Module 
    def array_attr_accessor(name) 
    define_method(name) do 
     if instance_variable_defined?("@#{name}") 
     instance_variable_get("@#{name}") 
     else 
     instance_variable_set("@#{name}", []) 
     end 
    end 

    define_method("#{name}=") do |val| 
     instance_variable_set("@#{name}", val) 
    end 
    end 
end 


class Test 
    array_attr_accessor :my 
end 

t = Test.new 
t.my # => [] 
t.my = [1,2,3] 
t.my # => [1, 2, 3] 
+0

編集を参照してください。 – sasuke

+0

私の悪い、私は "似ている"と言った。基本的に、この新しいメソッドは 'attr_accessor'のようなクラスに追加されると、そのクラスのために作成されたすべてのオブジェクトに新しいインスタンス変数を追加します。 – sasuke

+1

ああ、私が思ったように、私はデフォルトの 'attr_reader'をそのような属性に依存することはできません。ただ一つの最後の質問:インスタンス変数をRubyでJavaなどのために初期化する方法はありませんか? – sasuke

0

私はそれがなぜあなたはとても躊躇ちょうど迅速な初期化を記述するためにしている、とは思いません方法?

2
# as instance variable without initialize 
class Test1 
    def my; @my ||= [] end 

    attr_writer :my 
end 

t = Test1.new 
t.my 


# as class instance variable 
class Test2 
    @my = [] 

    class << self; attr_accessor :my end 
end 

Test2.my 
+1

+1、esp。アクセッサを使用したクラスレベル変数の場合'initialize'のないインスタンス変数は、' t.my = nil'を設定しようとすると、 't.my'は' || = 'のために' [] 'に戻ります。希望される; 「初期化」を避けないほうがよいでしょう。 – mklement0