ruby中的回调方法和钩子方法

  在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
[:m1, :method]

  如代码,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 got a new subclass E

  当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
1

  常量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中钩子方法很多,覆盖了绝大多数值得注意的事件。这里只给出一些常见的,给自己参考,给大家参考。

ruby中的回调方法和钩子方法

时间: 2024-10-07 18:48:33

ruby中的回调方法和钩子方法的相关文章

ruby中的链式访问和方法嵌套

先看一道题,这道题是codewars上的一道题,我很早就看到了,但是不会写.等到又看到这道题的时候,我刚看完元编程那本书,觉得是可以搞定它的时候了.废话不多说,先看这道题,题目最开始是为JavaScript写的,但是也放在了ruby语言里面,这个没有关系.题目内容是有一个类Calc,通过链式方法调用,可以实现加减乘除.如图给的四个例子.数字只有0-9,运算只有加减乘除,而且每个运算只有一个操作符.(可以先不看下面,自己先想一下怎么写) 首先,每一个例子都是同样的结构---类名和四个方法.拿第一个

java回调方法、钩子方法以及模板方法模式

在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类称为回调类,回调类的对象称为回调对象,其处理事件的方法叫做回调方法.(摘自百度百科) 那么通过上面那句话将百度百科中的"回调函数"翻译成JAVA版:回调方法就是一个通过回调对象的引用(java中的引用存的是对象的地址)调用的方法.如果你把 回调对象的引用(地址)作参数传递给另一个方法,当这个引用被用来调用其所指向的方法时,我们就说这是回调方法.回调方法不是由该方法的实现方直接调用,而是在特定的事件或条件发生时由

ruby中rsa加签解签方法

# coding:utf-8require 'openssl'require 'base64'# rsa签名,文本内容和私钥路径def rsa_sign(data,private_key_path) private_key = File.read(private_key_path) pri = OpenSSL::PKey::RSA.new(private_key) sign = pri.sign('sha1', data.force_encoding("utf-8")) # signa

Ruby中的遍历指定目录的文件方法

在ruby中我们要实现遍历指定目录的方法,网上的方法也非常之多,我们可以拿来参考参考,如下边的traverse.rb文件内容所示: #!/usr/bin/ruby  def traverse(filepath)     if File.directory?(filepath)       puts "Dirs:" + filepath       Dir.foreach(filepath) do |filename|         if filename != ".&quo

ruby中的可调用对象--方法

上一篇讲了ruby中的可调用对象proc和lambda,他们都是块转换成的对象.ruby中的可调用对象还有方法.通过使用method方法,并且以方法名作为参数(字符串或者符号),就可以得到一个方法对象. 如下: 1 class C 2 def talk 3 p "hello world" 4 end 5 end 6 7 c = C.new 8 meth = c.method :talk 9 meth.call 输出: "hello world" 类C有个实例方法ta

在 Ruby 中执行 Shell 命令的 6 种方法

我们时常会与操作系统交互或在 Ruby 中执行 Shell 命令.Ruby为我们提供了完成该任务的诸多方法. Exec Kernel#exec 通过执行给定的命令来替换当前进程,例如: $ irb >> exec 'echo "hello $HOSTNAME"' hello codefun $ 注意 exec 利用 echo 命令替换了 irb 进程,然后退出.因为 Ruby 实际上结束了该方法,所以只能有限使用.该方法的缺点是,你无法从 Ruby 脚本中知道命令是执行成功

js中的回调函数的理解和使用方法

一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为函数实际上是一种对象,它可以存储在变量中,通过参数传递给另一个函数,在函数内部创建,从函数中返回结果值",因为函数是内置对象,我们可以将它作为参数传递给另一个函数,到函数中执行,甚至执行后将它返回,它一直被"专业的程序员"看作是一种难懂的技术. 回调函数的英文解释为: A callback is a functi

ruby中的方法查找

ruby中的方法调用都是 对象.方法 的形式,那么对象如何找到这个方法呢? 首先必须了解祖先链的概念,祖先链就是从一个类开始,到它的父类,再到父类的父类...一直到最终的起点(ruby中是BasicObject类).这期间经历过的路径就是祖先链. 1混含模块和继承的方法查找 对于一个实例对象,先找它属于的类中是否有对应的实例方法,然后看这个类中是否有模块,如果有,查找模块中是否有对应的方法,如果没有,则查找父类.先看父类的实例方法,再看父类中是否有模块,再看父类的父类..一直到最后,BasicO

回调函数在replace方法中的应用

处理字符串是项目中经常会遇到的问题,对于长度比较大的字符串如何作一次性处理是需要我们去考虑的,这里给个例子: 把字符串"get-element-by-id"变成"getElementById": 方法一: var a = "get-by-element-by-id"; var b = a.split("-") for(var i = 1 ;i<b.length;i++){ b[i].charAt(0).toUpperCa