クラス外からインスタンス変数にアクセスする


82

インスタンス変数がクラスに属している場合、クラスインスタンスを使用してインスタンス変数(例@hello)に直接アクセスできますか?

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
puts h.method1

回答:


148

はい、次のinstance_variable_getように使用できます。

class Hello
  def method1
    @hello = "pavan"
  end
end

h = Hello.new
p h.instance_variable_get(:@hello) #nil
p h.method1                        #"pavan" - initialization of @hello
p h.instance_variable_get(:@hello) #"pavan"

変数が未定義の場合(instance_variable_get私の例ではの最初の呼び出し)、を取得しnilます。


アンドリューが彼のコメントで述べているように:

これはカプセル化に違反するため、インスタンス変数にアクセスするデフォルトの方法にしないでください。

より良い方法は、アクセサーを定義することです。

class Hello
  def method1
    @hello = "pavan"
  end
  attr_reader :hello  
end

h = Hello.new
p h.hello #nil
p h.method1                        #"pavan" - initialization of @hello
p h.hello #"pavan"

別のメソッド名が必要な場合は、アクセサーのエイリアスを作成できますalias :my_hello :hello

また、クラスがコードではなくgemで定義されている場合:コード内のクラス変更し、クラス新しい関数を挿入できます


6
あなたはすべきではない、それはカプセル化に違反するとして、あなたはインスタンス変数にアクセスし、このデフォルトの方法を確認します。
Andrew Marshall

@knutはh = Hello.newh.method1andとandのようにこれを行うことはできませんh.helloか?
nik7 2012

3
@nlingutlaあなたはとアクセサを定義することができますattr_reader :hello
クヌート

そうalias my_hello helloではないalias :my_hello :helloでしょうか?
モニカの訴訟に資金を提供する2015年

1
私にとって、これは何かを公​​開したくないスペックに最適です。
baash05 2018年

20

またattr_reader、次のattr_accessorように呼び出すか、このようにすることでこれを実現できます。

class Hello
  attr_reader :hello

  def initialize
    @hello = "pavan"
  end
end

または

class Hello
  attr_accessor :hello

  def initialize
    @hello = "pavan"
  end
end

を呼び出すattr_readergetter、指定された変数のが作成されます。

h = Hello.new
p h.hello        #"pavan"

を呼び出すattr_accessorと、指定された変数のgetterANDが作成さsetterれます。

h = Hello.new
p h.hello        #"pavan"
h.hello = "John"
p h.hello        #"John"

あなたが理解かもしれませんが、使用attr_readerしてattr_accessorそれに応じて。のみ使用しattr_accessor、あなたが必要とするときgetter、ANDsetterや使用attr_readerだけ必要なときgetter

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.