Enumerable作为一个枚举模块,被include到各种枚举类中,包括并不限于Array, hash等。

#查看Array中引入Enumerable
Array.ancestors #=>[Array, Enumerable, Object, Kernel, BasicObject]

下面介绍Enumerable的两个功能:

1.自定义的类中如何引入Enumerable的方法

2.介绍Enumerable中lazy方法的实现场景

引入Enumerable方法

使用场景:自定义类,同时想使用enumerable的方法

#3个条件,引入enumerable, 有初始化函数和初始化变量,存在each方法,并且有如下实现 
class DataModel
  #必须include enumerable
  include Enumerable

  #必须有初始化函数
  def initialize data
    @data = data
  end
  #按照enumerable的api介绍,为了实现遍历,查询以及排序的功能,必须实现each方法,代码内容如下
  def each
    @data.each{ |x| yield x }
  end
end

obj = DataModel.new([1,2,3])
obj.inspect #<DataModel:0x007fb67601e710 @data=[1, 2, 3]>
obj.to_a #[1,2,3]
demo = obj.select{ |x| x>2 }
#对比Array方法,理解上面的自定义引入并且实现Enumerable的方法
obj = Array.new([1,2,3])
obj.inspect #"[1, 2, 3]"
demo = obj.select{ |x| x>2 }  #综合对比可以看出,进行遍历和选择的是对象在初始化过程中对象的变量

lazy加载

使用场景:数据比较多的情况,比如要统计文件内容中每行数据的匹配,如果文件内容比较多的话,需要使用懒加载

#实例
a = [1,2,3]
a.select{ |x| x>2 } #在遍历a的时候,a数组中变量已经生成,这个不是懒加载,懒加载是遍历到a中变量的时候才加载这个数据

#场景,从所有证书中找到被27整除的数
(1..Float::INFINITY).to_a #报错,Float::INFINITY是无穷大,(1..Float::INFINITY).to_a会加载全部数据
(1..Float::INFINITY).select{ |x| x%27==0 }.take(10) #报错,执行到select,会加载全部数据
(1..Float::INFINITY).lazy.select{ |x| x%27==0 }.lazy.take(10) #不会加载全部,加载一个,执行一个,就是懒加载

#常用场景:使用懒加载读取大型文件
file = File.open("demo.rb", "r")
file.each_line.lazy.select{|x| x=~/demo/ }

results matching ""

    No results matching ""