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
。
更新:正如安德鲁马歇尔所说,不完全是。大多数 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
如您所见,它只是使用传递的符号来创建两个方法。它并没有对符号做任何花哨的事情,而且大多只是通过它。另请注意,所有实例变量默认“存在”并设置为nil
,因此这永远不会爆炸。