Ruby's Enumerable Module and yield method

简介:
Hash, Array, Range, Set 类的对象为什么可以使用include?, min, max等方法, 原因是这些CLASS包含了Enumerable模块.
这个模块的详细介绍可以在Ruby Core API Reference中查询.
下面对某些方法举例说明 : 
测试版本1.9.3-p0
一、内建类型的Enumerable方法调用
1. min
a = Array.new(['z','abc','bc','d1','efg'])
p(a.min)   #=>"abc" , 默认情况下min 判断的是ascii码
p(a.min{
 |x|
 x.length
 })  #=>"z" , 这里判断的是字符长度.


2. max
a = {'z'=>'digoal',
 'abc'=>'francs',
 'bc'=>'dage',
 'd1'=>'hank',
 'efg'=>'new'}
p(a) #=>{"z"=>"digoal", "abc"=>"francs", "bc"=>"dage", "d1"=>"hank", "efg"=>"new"}
p(a.max) #=>["z", "digoal"]
p(a.max{
 |x|
 x.length
 }) #=>["efg", "new"] , 这里判断的是hash key的字符长度.


3. sort
a = {'z'=>'digoal',
 'abc'=>'francs',
 'bc'=>'dage',
 'd1'=>'hank',
 'efg'=>'new'}
p(a) #=> {"z"=>"digoal", "abc"=>"francs", "bc"=>"dage", "d1"=>"hank", "efg"=>"new"}
p(a.sort) #=> [["abc", "francs"], ["bc", "dage"], ["d1", "hank"], ["efg", "new"], ["z", "digoal"]] , 默认按ASCII排序
p(a.sort{
 |x,y|
 x[0].length <=> y[0].length
 }) #=> [["z", "digoal"], ["d1", "hank"], ["bc", "dage"], ["abc", "francs"], ["efg", "new"]]  , 这里按照Hash key的长度排序
p(a.sort{
 |x,y|
 x[1].length <=> y[1].length
 }) #=> [["efg", "new"], ["d1", "hank"], ["bc", "dage"], ["abc", "francs"], ["z", "digoal"]] , 这里按照Hash value的长度排序


4. collect
a = [1,2,3,4,5,6]
b = a.collect {
 |x|
 x * x
}
p(a) #=> [1, 2, 3, 4, 5, 6]
p(b) #=> [1, 4, 9, 16, 25, 36] , collect方法重新构造一组数据.


5. include?
a = [1,2,3,4,5,6]
p(a.include?(1)) #=> true , 判断是否包含1
p(a.include?(7)) #=> false , 判断是否包含7


二、自定义CLASS中包含Enumerable模块举例 : 
class MyClass
 include Enumerable # 这个指包含Enumerable模块
 def initialize( someItems )
  @items = someItems
 end

 def each # 要在自定义类中使用Enumerable模块中的方法, 必须写一个each 方法, 告诉其他要调用的Enumerable方法每次传什么值进去.
  @items.each{
                       |i|
   yield(i)  # yield方法里面的参数, 就是表示其他要调用的Enumerable方法每次传什么值进去.这里每次传的就是i
  }
 end
end

a = MyClass.new(['c','bda1a','baz','ce','zwfg'])
p(a) #=> #<MyClass:0x1ef0db0 @items=["c", "bda1a", "baz", "ce", "zwfg"]>
p(a.sort) #=> ["baz", "bda1a", "c", "ce", "zwfg"]

class MyClass
 include Enumerable
 def initialize( someItems )
  @items = someItems
 end

 def each
  @items.each{
   |i|
   yield(i.to_s.length) #这里每次传的是i.to_s.length
  }
 end
end

a = MyClass.new(['c','bda1a','baz','ce','zwfg'])
p(a) # => #<MyClass:0x1e90c90 @items=["c", "bda1a", "baz", "ce", "zwfg"]>
p(a.sort) # => [1, 2, 3, 4, 5]

# 自定义类型中如果没有定义each方法, 但是调用了Enumerable中的方法会报错, 例如 : 
`sort': undefined method `each' for #<MyClass:0x1ebfb08 @items=["c", "bda1a", "baz", "ce", "zwfg"]> (NoMethodError)

【参考】
Ruby Core API Reference : Enumerable
The Book of Ruby : Page 100 - 105
相关文章
|
3月前
|
Python
python tkinter Tcl_AsyncDelete: async handler deleted by the wrong thread
python tkinter Tcl_AsyncDelete: async handler deleted by the wrong thread
37 1
|
5月前
|
Python
Python报错: No module named 'requests'
Python报错: No module named 'requests'
77 1
|
8月前
|
PyTorch 算法框架/工具 Python
AttributeError: module ‘distutils‘ has no attribute ‘version‘解决跑pytorch代码报错
AttributeError: module ‘distutils‘ has no attribute ‘version‘解决跑pytorch代码报错
|
10月前
|
Ruby
浅谈Ruby中的block, proc, lambda, method object的区别
浅谈Ruby中的block, proc, lambda, method object的区别
61 0
|
Python
Python3 多线程问题:ModuleNotFoundError: No module named 'thread',原因及解决办法。
Python3 多线程问题:ModuleNotFoundError: No module named 'thread',原因及解决办法。
706 0
|
C# Python
python与C#的互相调用(No module named XX)
python与C#的互相调用(No module named XX)
python与C#的互相调用(No module named XX)
|
Python
Python 库升级问题-module ‘requests.exceptions‘ has no attribute ‘ReadTimeout‘原因及解决办法
Python 库升级问题-module ‘requests.exceptions‘ has no attribute ‘ReadTimeout‘原因及解决办法
316 0
Python 库升级问题-module ‘requests.exceptions‘ has no attribute ‘ReadTimeout‘原因及解决办法