庇护祝福的分享

Be worthy

Ruby元编程四:类定义

类定义

在ruby中,类定义和其他语言有所不同,当使用class关键字时,并非是在指定对象未来的行为方式,实际上是在运行代码。 类定义会返回最后一条语句的值。 每当通过class关键字打开一个类,这个类就成为当前类。在类定义中,当前对象self就是正在定义的类。

类实例变量

class MyClass
    @var = 0
    def self.method_one
        @var = 1
    end

    def method_two
        @var = 2
    end

    def method_three
        @var = 3
    end

    class<<self 
        def method_four
            x=4
        end

        def method_five
            x=5
        end
    end
end

obj = MyClass.new
obj.method_two           #=>2
obj.method_threee        #=>3
MyClass.method_one       #=>1
类实例变量只有类可以调用它,而类的实例则不行,实例变量则正好相反。
class<<self 用于一次性定义多个类方法

类变量

以@@开头,它们可以被子类或者类的实例所使用 后定义的同名类变量会覆盖之前的,不论它的位置,example:

@@v = 1
class A
  @@v = 2
end
@@v                        #=>2

扁平化作用域

使用class, def, module关键字会产生作用域门.但是如果想在一个模块中共享变量,就需要用到扁平化作用域. 使用ClassName = Class.new , ModuleName = module.new , define_method: method_name do ….end example:

    my_var = "success"
    MyClass = Class.new do
      puts "#{my_var} is get"
      define_method :printvar do
        puts "#{my_var} is in the method"
      end
    end
    MyClass.new.printvar

单件方法与类方法

Ruby允许给单个对象添加方法,这就是单件方法。example:

str = "hahaha"
def str.title?
    self.upcase == self
end

而类方法实际就是一种单件方法,因为类也是对象,它针对这个类生效。

类宏

Ruby对象没有属性,如果想要定义属性,就需要定义两个拟态方法,一个读方法和一个写方法。

class MyClass
    def height=(val)
        @height = val
    end

    def height
        @height
    end
end
obj = MyClass.new
obj.height = "160cm"
obj.height     #=>"160cm"

这样非常麻烦,我们可以使用module#attr_*系列方法,其中attr_reader()可以生成一个读方法;attr_writer()可以生成写方法;attr_accessor()则可以生成读写方法。
那么上面的例子就可以改写为:

class MyClass
    attr_accessor :height
end

环绕别名

从一个重新定义的方法中调用原始的,被重命名的版本。 三个步骤: 1. 通过alias 对原有方法定义一个别名 2. 覆写原有方法 3. 在该方法中调用别名方法 这样做的好处,可以改写原有方法,又不破坏原有功能 。

    class String  
        alias :old_reverse :reverse
        def reverse 
            "x#{old_reverse}x"
        end
    end 
    "abc".reverse  =>xcbax