在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在ruby中,当某些特定的事件发生时,将调用回调方法和钩子方法。事件有如下几种:
对以上的事件,都可以为之编写一个回调方法,当该事件发生时,这个回调方法被执行。这些回调方法是针对某个对象,或者某个类的,而不是全局的。
下面给出一些例子: 1 Method_missing拦截不能识别的消息 在前面说过,根据对象模型来进行方法查找,如果没有找到,会抛出一个NoMethodError异常,除非定义了一个名为method_missing的方法。 如下: 1 class C 2 def method_missing(m) 3 puts "there is no method #{m}" 4 end 5 end 6 C.new.hello 输出: there is no method hello 类C中没有定义实例方法hello(它的方法查找路径上也没有),因此调用method_missing。
2 用Module#included捕捉混含操作 当一个模块被混入到类(或者另一个模块)中,如果该模块的included方法已经定义,那么该方法就会被调用。该方法的参数就是混入该模块的类。 如下: 1 module M 2 def self.included(c) 3 puts "module M is included by #{c}" 4 end 5 end 6 class C 7 include M 8 end 输出: module M is included by C 当模块M被混入到C中,模块M的included方法被调用了。 这种方式可以用来定义类方法,如上面的代码中,在self.included中就可以定义类c的类方法,或者给单例类添加一个模块 如下: 1 module M 2 def self.included(c) 3 puts "module M is included by #{c}" 4 5 def c.m1 6 puts "this is class #{c}'s class method m1 " 7 end 8 9 c.extend(N) 10 end 11 module N 12 def method 13 puts "hello world" 14 end 15 end 16 end 17 class C 18 include M 19 end 20 p C.singleton_methods 输出: module M is included by C 如代码,5-7行定义了一个类方法,该类是包含模块M的类(此例中就是C),9行将模块N加入了该类的单例类中。在20行的输出类C的单例方法可以看出加入成功。
3 用Class#inherited拦截继承 当为一个类定义了inherited方法,那么在为它生成子类时,inherited会被调用,唯一的调用参数就是新的子类的名字。 如下: 1 class C 2 def self.inherited(subclass) 3 puts "#{self} got a new subclass #{subclass} " 4 end 5 end 6 class D < C 7 end 8 class E < D 9 end 输出: C got a new subclass D 当D继承C时,调用了这个钩子方法,输出C got a new subclass D。同时,D的单例类中也有了C的类方法,因此在E继承D时,也会调用调用D的这个钩子方法。
4 Module#const_missing 当给定的模块或者类中引用了一个不可识别的常量时,该方法被调用。 如下: 1 class C 2 def self.const_missing(const) 3 puts "#{const} is undefined-setting " 4 const_set(const,1) 5 end 6 end 7 puts C::A 输出 A is undefined-setting 常量A没有被定义,因此调用了const_missing方法。在方法中把它定义为1。
5 Module#method_added 当新定义一个方法时,会调用这个方法。 如下: 1 module M 2 def self.method_added(method) 3 puts "method #{method} is added in M" 4 end 5 def m1 6 end 7 end 输出 method m1 is added in M
ruby中钩子方法很多,覆盖了绝大多数值得注意的事件。这里只给出一些常见的,给自己参考,给大家参考。
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论