当我们在以下代码中为name
定义getter和setter方法时:
class Animal
attr_accessor :name
def initialize(name)
@name = name
end
end
内部发生了什么? Ruby如何获取符号并将其与变量匹配?
答案 0 :(得分:6)
它使用instance_variable_get
和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元编程的介绍性文本,例如"Don’t Know Metaprogramming In Ruby?"。
答案 1 :(得分: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
如您所见,它只是使用传递的符号来创建两个方法。它没有对符号做任何花哨的事情,而且大部分只是通过它。另请注意,默认情况下所有实例变量都“存在”并设置为nil
,因此永远不会爆炸。