web-dev-qa-db-ja.com

指定された名前のインスタンス変数の値を取得します

一般に、文字列に名前があるオブジェクトへの参照を取得するにはどうすればよいですか?

より具体的には、パラメーター名のリストがあります(メンバー変数-動的に構築されているため、直接参照できません)。

各パラメーターは、from_sメソッドも持つオブジェクトです。

私は次のようなことをしたいです(もちろんうまくいきません...):

define_method(:from_s) do | arg |
    @ordered_parameter_names.each do | param |
        instance_eval "field_ref = @#{param}"
        field_ref.from_s(param)
    end
end
94
LK__

これを実現する最も慣用的な方法は次のとおりです。

_some_object.instance_variable_get("@#{name}")
_

_+_またはintern;を使用する必要はありません。 Rubyはこれをうまく処理します。ただし、別のオブジェクトに到達してそのivarを引き出すことに気付いた場合は、カプセル化が壊れている可能性がかなりあります。

明示的にivarにアクセスしたい場合、正しいことはそれをアクセサにすることです。以下を考慮してください。

_class Computer
  def new(cpus)
    @cpus = cpus
  end
end
_

この場合、_Computer.new_を実行した場合、_instance_variable_get_を使用して_@cpus_を取得する必要があります。ただし、これを行う場合は、おそらく_@cpus_がパブリックであることを意味します。あなたがすべきことは:

_class Computer
  attr_reader :cpus
end
_

これで、Computer.new(4).cpusを実行できます。

any既存のクラスを再度開き、プライベートivarをリーダーにすることができることに注意してください。アクセサーは単なるメソッドであるため、Computer.new(4).send(var_that_evaluates_to_cpus)を実行できます

171
Yehuda Katz

インスタンス変数の名前からインスタンス変数を取得するには、次のようにします。

name = "paramName"
instance_variable_get(("@" + name).intern)

これは、インスタンス変数@paramNameの値を返します

9
Daniel Lucraft