web-dev-qa-db-ja.com

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

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

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

h = Hello.new
puts h.method1
77
Pawan

はい、次のように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"

別のメソッド名が必要な場合は、アクセサをaliasalias :my_hello :helloにできます。

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

132
knut

次のように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_readerを呼び出すと、指定された変数のgetterが作成されます。

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

attr_accessorを呼び出すと、指定された変数に対してgetter AND setterが作成されます。

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

ご理解のとおり、それに応じてattr_readerおよびattr_accessorを使用してください。 getterおよびsetterが必要な場合にのみattr_accessorを使用し、getterのみが必要な場合にattr_readerを使用します

11
Kevinvhengst