本帖最后由 shitake 于 2016-4-15 22:43 编辑
感谢 晴兰 的提醒,更正了之前“类宏是单件方法”的错误。。。实际上从下边定义my_attr_* 就可以看出。。。单件方法的话应该是 def self.my_attr_* 。囧
attr_* 系列的方法,通常被称为类宏(class macro Metaprogramming Ruby 2 p116)。所谓类宏,就是在一个类定义中使用一个类方法 ,这个类方法对该类做了宏扩展。
然后再说说ruby里的属性。实际上ruby里的对象是没有属性这个概念的。当我们为一个类定义属性时,实际上是定义了两个拟态方法:
class MyClass def attribute=(value) @attribute = value end def attribute @attribute end end myclass = MyClass.new myclass.attribute = 233 p myclass.attribute # => 233
class MyClass
def attribute=(value)
@attribute = value
end
def attribute
@attribute
end
end
myclass = MyClass.new
myclass.attribute = 233
p myclass.attribute # => 233
拟态方法(Mimic Method)
像上面例子里定义的 attribute/attribute= 的这一类方法,通常又被称为访问器。如果每一个属性都通过这样来手工定义,则会十分繁琐。因此有了attr_* 这一系列的方法。这些方法定义在Module类中。attr_reader 定义了读的方法,attr_writer 定义了写的方法,attr_accessor 定义了读写的方法。
#attr* 系列方法的简单非官方实现 class Class def my_attr_reader(attr_name) define_method(attr_name) do instance_variable_get('@' + attr_name.id2name) end end def my_attr_writer(attr_name) define_method( (attr_name.id2name + '=').to_sym ) do |value| instance_variable_set('@'+attr_name.id2name, value) end end def my_attr_accessor(attr_name) my_attr_reader(attr_name) my_attr_writer(attr_name) end end class MyClass my_attr_accessor :params end myclass = MyClass.new p myclass.params # => nil myclass.params = 233 p myclass.params # => 233
#attr* 系列方法的简单非官方实现
class Class
def my_attr_reader(attr_name)
define_method(attr_name) do
instance_variable_get('@' + attr_name.id2name)
end
end
def my_attr_writer(attr_name)
define_method( (attr_name.id2name + '=').to_sym ) do |value|
instance_variable_set('@'+attr_name.id2name, value)
end
end
def my_attr_accessor(attr_name)
my_attr_reader(attr_name)
my_attr_writer(attr_name)
end
end
class MyClass
my_attr_accessor :params
end
myclass = MyClass.new
p myclass.params # => nil
myclass.params = 233
p myclass.params # => 233
|