ruby中的回调方法和钩子方法
在ruby中,当某些特定的事件发生时,将调用回调方法和钩子方法。事件有如下几种:
- 调用一个不存在的对象方法
- 类混含一个模块
- 定义类的子类
- 给类添加一个实例方法
- 给对象添加一个单例方法
- 引用一个不存在的常量
对以上的事件,都可以为之编写一个回调方法,当该事件发生时,这个回调方法被执行。这些回调方法是针对某个对象,或者某个类的,而不是全局的。
下面给出一些例子:
1 Method_missing拦截不能识别的消息
在前面说过,根据对象模型来进行方法查找,如果没有找到,会抛出一个NoMethodError异常,除非定义了一个名为method_missing的方法。
如下:
class C
def method_missing(m)
puts "there is no method #{m}"
end
end
C.new.hello
输出:
there is no method hello
类C中没有定义实例方法hello(它的方法查找路径上也没有),因此调用method_missing。
2 用Module#included捕捉混含操作
当一个模块被混入到类(或者另一个模块)中,如果该模块的included方法已经定义,那么该方法就会被调用。该方法的参数就是混入该模块的类。
如下:
module M
def self.included(c)
puts "module M is included by #{c}"
end
end
class C
include M
end
输出:
module M is included by C
当模块M被混入到C中,模块M的included方法被调用了。
这种方式可以用来定义类方法,如上面的代码中,在self.included中就可以定义类c的类方法,或者给单例类添加一个模块
如下:
module M
def self.included(c)
puts "module M is included by #{c}" def c.m1
puts "this is class #{c}'s class method m1 "
end c.extend(N)
end
module N
def method
puts "hello world"
end
end
end
class C
include M
end
p C.singleton_methods
输出:
module M is included by C
[:m1, :method]
如代码,5-7行定义了一个类方法,该类是包含模块M的类(此例中就是C),9行将模块N加入了该类的单例类中。在20行的输出类C的单例方法可以看出加入成功。
3 用Class#inherited拦截继承
当为一个类定义了inherited方法,那么在为它生成子类时,inherited会被调用,唯一的调用参数就是新的子类的名字。
如下:
class C
def self.inherited(subclass)
puts "#{self} got a new subclass #{subclass} "
end
end
class D < C
end
class E < D
end
输出:
C got a new subclass D
D got a new subclass E
当D继承C时,调用了这个钩子方法,输出C got a new subclass D。同时,D的单例类中也有了C的类方法,因此在E继承D时,也会调用调用D的这个钩子方法。
4 Module#const_missing
当给定的模块或者类中引用了一个不可识别的常量时,该方法被调用。
如下:
class C
def self.const_missing(const)
puts "#{const} is undefined-setting "
const_set(const,1)
end
end
puts C::A
输出
A is undefined-setting
1
常量A没有被定义,因此调用了const_missing方法。在方法中把它定义为1。
5 Module#method_added
当新定义一个方法时,会调用这个方法。
如下:
module M
def self.method_added(method)
puts "method #{method} is added in M"
end
def m1
end
end
输出
method m1 is added in M
ruby中钩子方法很多,覆盖了绝大多数值得注意的事件。这里只给出一些常见的,给自己参考,给大家参考。
ruby中的回调方法和钩子方法的更多相关文章
- ruby中的链式访问和方法嵌套
先看一道题,这道题是codewars上的一道题,我很早就看到了,但是不会写.等到又看到这道题的时候,我刚看完元编程那本书,觉得是可以搞定它的时候了.废话不多说,先看这道题,题目最开始是为JavaScr ...
- java回调方法、钩子方法以及模板方法模式
在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类称为回调类,回调类的对象称为回调对象,其处理事件的方法叫做回调方法.(摘自百度百科) 那么通过上面那句话将百度百科中的&qu ...
- JavaScript中的回调地狱及解决方法
1.回调地狱 在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱.比如说你要把一个函数 A 作为回调函数,但 ...
- Ruby中Enumerable模块的一些实用方法
我在查看 Array 类和 Hash 类的祖先链的时候都发现了 Enumerable,说明这两个类都mixin了Enumerable模块.Enumerable模块为集合型类提供了遍历.检索.排序等方法 ...
- ruby中rsa加签解签方法
# coding:utf-8require 'openssl'require 'base64'# rsa签名,文本内容和私钥路径def rsa_sign(data,private_key_path) ...
- windows下ruby中显示中文的3种方法
A: 1将x.rb编码为ascii格式 2 在x.rb开头加上 #code:gbk或者 #coding:gbk B: 1 将x.rb编码为utf-8格式 2 在x.rb开头加上 #code:utf-8 ...
- ruby中如何调用与局部变量同名的私有方法
如果ruby中一个局部变量名和私有方法名同名的话,默认该名称被解释为变量而不是方法: x=10; def x;puts "what?" end 当你输入x实际不能执行x方法.解释器 ...
- ruby中的可调用对象--方法
上一篇讲了ruby中的可调用对象proc和lambda,他们都是块转换成的对象.ruby中的可调用对象还有方法.通过使用method方法,并且以方法名作为参数(字符串或者符号),就可以得到一个方法对象 ...
- java设计模式之模板模式以及钩子方法使用
1.使用背景 模板方法模式是通过把不变行为搬到超类,去除子类里面的重复代码提现它的优势,它提供了一个很好的代码复用平台.当不可变和可变的方法在子类中混合在一起的时候, 不变的方法就会在子类中多次出现, ...
随机推荐
- Android 读写位于SD卡上的sqlite数据库文件错误问题
09-12 15:24:33.903: W/System.err(19499): java.lang.NullPointerException: Attempt to invoke virtual m ...
- js将字符串转换为数字等类型
1.js提供了parseInt()和parseFloat()两个转换函数. 2.ECMAScript中可用的3种强制类型转换如下: Boolean(value)——把给定的值转换成Boolean型: ...
- linux文件锁flock【转】
转自: https://www.cnblogs.com/kex1n/p/7100107.html linux文件锁flock 在多个进程同时操作同一份文件的过程中,很容易导致文件中的数据混乱,需要 ...
- CSS写表格
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content_Type" content ...
- JS-制作留言提交系统(支持ctrl+回车)
弹出键值说明: //console.log(ev.keyCode)//回车:13//ctrl:17 <!DOCTYPE html> <html> <head> &l ...
- LeetCode——Single Number III
Description: Given an array of numbers nums, in which exactly two elements appear only once and all ...
- LeetCode——Happy Number
Description: Write an algorithm to determine if a number is "happy". A happy number is a n ...
- install kubernetes dashboard 安装 kubernetes dashboard 详细
参考: http://www.bubuko.com/infodetail-2242562.html http://www.cnblogs.com/zhenyuyaodidiao/p/6500897.h ...
- 【BZOJ2938】[Poi2000]病毒 AC自动机+DFS
[BZOJ2938][Poi2000]病毒 Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码 ...
- CentOS7安装步骤详解
准备环境 1.虚拟机 VMware Workstation 2.Centos7-64位安装包 ( CentOS-6.7-x86_64-bin-DVD1.iso ) 开始安装 进入安装初始化界面 ...