Ruby元编程读书笔记十三
Class Variables
如果希望在类中存储一个变量,那么除了 类实例变量,还可以使用以 @@ 开头的 类变量。类变量与类实例变量不同,它们可以被子类或类的实例所使用:
class C
@@v = 1
end
class D < C
def my_method; @@v; end
end
D.new.my_method #=> 1
所有的类都是是 Class 类的实例,所以可以通过调用 Class.new() 方法来创建类。 Class.new() 方法还可以接受一个参数(所建新类的超类)以及一个块:
c = Class.new(Array) do
def my_method
'Hello!'
end
end
现在虽然有了一个引用类的变量,但是这个类还是匿名的。类名不过是一个常量而已,因此可以来给它赋值:
MyClass = c
这样,该常量就表示这个 class,同时这个 class 也表示这个常量:
c.name #=> "MyClass"
Singleton Methods
Ruby 允许给单个对象增加一个方法。
str = "just a regular string"
def str.title?
self.upcase == self
end
str.title? #=> flase
str.methods.grep(/title?/) #=> ["title?"]
str.singleton_methods #=> ["title?"]
上面的代码为 str 添加了一个 title?() 方法,其他对象则不会得到这个方法—-即使是其他的 String 对象。像这样只针对单个对象生效的方法,称为 单件方法。
The Truth About Class Methods
类只是对象,而类名只是常量,在类上调用方法就跟在对象上调用方法一样:
an_object.a_method
AClass.a_class_method
类方法的实质就是—-它们是一个类的单件方法。如果比较单件方法的定义和类方法的定义,会发现它们是一样的:
def obj.a_singleton_method;end
def MyClass.another_class_method;end
如果在类定义中写入代码,由于这时 self 就是类本身,所以还可以利用这一点用 self 替换类名来定义类方法:
class MyClass
def self.yet_another_class_method;end
end
Class Macros
Ruby 对象并没有属性,如果希望有一些像属性的东西,就得定义两个 拟态方法 —-一个读方法和一个写方法:
class MyClass
def my_attribute=(value)
@my_attribute = value
end
def my_attribute
@my_attribute
end
obj = MyClass.new
obj.my_attribute = 'x'
obj.my_attribute #=> "x"
写这样的方法很快就让人感到枯燥,其实你可以通过使用 Module#attr_*() 方法家族中的一员来定义访问器。Module#attr_reader() 可以生成一个读方法, Module#attr_writer() 可以生成一个写方法,而 Module#attr_accessor() 则可以同时生成两者:
class MyClass
attr_accessor :my_attribute
end
所有的 attr*() 方法都定义在 Module 类中,因此不管 self 是类还是模块,都可以使用它们。像 attr_accessor() 这样的方法被称为 类宏。虽然类宏看起来很像关键字,但是它们只是普通的方法,只是可以用在类定义中而已。