name
次のコードでgetter メソッドと setter メソッドを定義しているとき:
class Animal
attr_accessor :name
def initialize(name)
@name = name
end
end
内部で何が起こっているのですか?Ruby はどのようにしてシンボルを取得し、それを変数と一致させることができますか?
name
次のコードでgetter メソッドと setter メソッドを定義しているとき:
class Animal
attr_accessor :name
def initialize(name)
@name = name
end
end
内部で何が起こっているのですか?Ruby はどのようにしてシンボルを取得し、それを変数と一致させることができますか?
instance_variable_get
そのためにandを使いinstance_variable_set
ます。
更新: Andrew Marshall が指摘したように、正確ではありません。ほとんどの Ruby コア メソッドは C で定義されていますが、結果は本質的に同じです。
attr_accessor
アンド フレンドを次のように定義できます。
def self.attr_accessor(*names)
names.each do |name|
define_method(name) do
instance_variable_get("@#{name}")
end
define_method("#{name}=") do |new_value|
instance_variable_set("@#{name}", new_value)
end
end
end
define_method
ここでは、アクセサー メソッドを定義するためにも使用していることに注意してください。
「Ruby のメタプログラミングがわからない?」など、Ruby のメタプログラミングに関する入門書を参照することをお勧めします。.
変数とは一致しません。attr_accessor
本質的にこれを行います (実際には C で記述されていますが、ここではおおまかに Ruby 翻訳で記述しています)。
def attr_accessor(var_name)
ivar_name = :"@#{var_name}"
define_method(var_name) do
instance_variable_get ivar_name
end
define_method("#{var_name}=") do |value|
instance_variable_set ivar_name, value
end
end
ご覧のとおり、渡されたシンボルを使用して 2 つのメソッドを作成するだけです。シンボルに特別なことは何もせず、ほとんどの場合、シンボルを通過させるだけです。また、すべてのインスタンス変数はデフォルトで「存在」し、 に設定されてnil
いるため、これが爆発することはありません。