4

name次のコードでgetter メソッドと setter メソッドを定義しているとき:

class Animal
    attr_accessor :name
    def initialize(name)
        @name = name
    end
end

内部で何が起こっているのですか?Ruby はどのようにしてシンボルを取得し、それを変数と一致させることができますか?

4

2 に答える 2

6

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 のメタプログラミングに関する入門書を参照することをお勧めします。.

于 2012-10-06T15:26:33.100 に答える
2

変数とは一致しません。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いるため、これが爆発することはありません。

于 2012-10-06T15:28:40.533 に答える