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() 这样的方法被称为 类宏。虽然类宏看起来很像关键字,但是它们只是普通的方法,只是可以用在类定义中而已。