ruby元编程——方法

来源:互联网 发布:minecraft服务器优化 编辑:程序博客网 时间:2024/06/14 22:37



  • 动态方法:
  • 幽灵方法:
  • 动态方法:

        (1)当调用一个对象的方法时,实际上是给一个对象发送了一条消息,ruby中Object#send()方法是,对方法调用本质的诠释,例:

        obj.me_method(3)  #与 obj.send(:my_method, 3)等价

        使用send()方法调用方法,方法名可以成为一个参数,即可以动态的调用方法,这种技术叫做动态派发

        (2)可以利用Module#define_method()方法定义一个方法,结合Object#send()既可以动态的定义方法,大量减少重复代码

    幽灵方法:

        (1)method_missing()是一个kernel方法,当解释器找不到对象调用的方法时,就会调用method_missing()方法,所以可以通过重写method_missing()方法来使用幽灵方法

        (2)幽灵方法存在一些需要注意的地方:

                幽灵方法并不是实际存在的方法,所有 respond_to?()方法会返回false,所以在使用幽灵方法时最好也重写respond_to?()方法,同时,methods()等一些列出方法名的方法返回结果中并不会有幽灵方法

                幽灵方法相对于正常的方法响应时间更长,由于在方法查找时会将整个祖先链走完,才能在最后调用method_missing()方法

                 幽灵方法可能会和一个真实的方法名冲突,这时是调用不到幽灵方法的,可以Module#undef_method()方法,他会删除所有的(包括继承来的)方法,或者使用Module#remove_method()方法,它只会删除接受者自己的方法。最好的方式还是使用白板类

                 当重写method_missing()的代码中出现调用没有定义的方法,会造成死循环。

        (3)幽灵方法示例:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class MyOpenStruct
        def initialize
            @attributes = {}
        end
        def method_messing(name, *args)
            attributes = name.to_s
            if attributes =~ /=$/
                @attributes[attribute.chop] = args[0]
            else
                @attributes[attribute]
            end
        end
    end
    icecream = MyOpenStruct.new
    icecream.flavor = "vanilla"
    icecream.flavor                                  # => "vanilla"

        (4)除了Object#method_missing()方法,还有Module#const_missing()方法,当引用一个不存在的常量时,会被调用

        (5)方法查找时,先找到接收者的类,再沿着父类向上查找(忽略eigenclass的情况下),由于图已经比较乱了,Class类的class箭头没有给出,Class.class   #=> Class

    0 0
    原创粉丝点击