Ruby 开发(五) - 模块(下)

179 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

五、method_missing 的使用

使用对象调用一个类或者一个实例的某个方法时,如果系统没有找到这个方法时会自动调用一个函数,这个函数就称为自动提供错误处理的回调函数

在 Ruby 中,自动调用提供错误处理的回调函数属于动态语言特性的一种,这里提供的 method_missing 方法就是用于处理方法找不到时的错误,method_missing 方法的用处非常广发,比如当调用一个遗漏的方法时,程序就会调用 method_missing 方法,并将这个方法的符号和参数传给 method_missing 函数。

class Xray
  def miss
    puts "这是 miss 方法"
  end

  def method_missing pd
    puts "Xray 类中不存在 #{pd.to_s} 的实例方法"
  end

  def self.method_missing pd
    "Xray 类中不存在 #{pd.to_s} 的类方法"
  end
end

xray = Xray.new
puts xray.miss
puts xray.hi
puts Xray.Hello

执行上述代码,输出结果如下:

这是 miss 方法

Xray 类中不存在 hi 的实例方法

Xray 类中不存在 Hello 的类方法

上述代码中定义了 method_missing pd 实例方法和 self.method_missing pd 类方法来判断是否存在实例方法和类方法。

class Find
  def self.post
    puts "https://juejin.cn"
  end

  def self.method_missing pd
    puts "输入地址有误,请重新输入"
  end
end

puts Find.post
puts Find.show

执行上述代码,输出结果如下:

https://juejin.cn

输入地址有误,请重新输入


六、Duck Typing 特性

Ruby 中有一种动态语言特性,称为 ”鸭子类型 duck typing“,duck typing 是一种实用主义的面向对象方法, 它对对象没有约定,只有在运行时进行检查,入股哦作为参数的对象拥有需要的方法和属性,就符合实用的要求。对 duck typing 的一个感性的认识就是,”当看到一只天鹅走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只天鹅就可以成为鸭子“。

duck typing 同样也可以是现在静态语言中,只不过要编译时识别和指定这些动态类。

七、Proc 对象

Ruby 中可以将一段代码绑定到一起形成一个代码块,并且在任何时候都可以访问代码块中的变量。

Proc 对象即是对块以及其局部变量的作用域进行对象化处理后得到的过程对象,导入到 Proc 内的局部变量没有作用域的问题,也就是说,Proc 内的局部变量会让你得到动态局部变量的效果

当希望向其他方法传递一块作为参数的代码,类似处理数据,这个时候就需要用到 Proc 对象。

proc = Proc.new{
  puts "实例化一个 Proc 对象"
}

上述代码并不会马上执行,只是作为 Proc 对象的一个定义被保存了下了,如果要执行它,需要发送 call 消息给这个对象

proc.call

执行上述代码,输出结果如下:

实例化一个 Proc 对象

方法定义体中的局部变量和方法调用作用域中的局部变量是没有任何关系的,当 Proc.new 调用时,作用域中的局部变量仍处于作用域中,也就是说无论何时何地调用该对象,那些变量始终都在 Proc 对象的作用域中

def call_proc(pr)
  a = "内部声明的变量"
  puts a
  pr.call
end

a = "外部声明的变量"
pr = Proc.new{
  puts a
}
pr.call
call_proc(pr)

执行上述代码,输出结果如下:

外部声明的变量
内部声明的变量
外部声明的变量

上述代码中,首先在外部作用域中生命了一个变量 a,接着建立了一个过程对象,然后调用这个过程对象,因此输出了 ”外部声明的变量“,接着是调用 call_proc 方法,该方法中定义了一个变量 a = "内部声明的变量",因或首先输出这个 a 的内容,接着又通过实例化的 Proc 对象调用了 call 方法,Proc 实例化时输出了外部定义的 a = "外部声明的变量",因此最后会输出 “外部声明的变量”。

Proc 对象是一个代码块的封装体,在 Ruby 中定义方法时,在方法的最后一个形参前添加一个 &,程序会将这个形参作为一个 Proc 对象来处理。

def grab_blc(&blc)
  blc.call
end

grab_blc do
  puts "我是 Proc 对象"
end

指向上述代码,输出结果如下:

我是 Proc 对象