我正在学习Ruby,在学习模块时,我发现为了使可枚举的模块方法可以在类中访问,还应该在类中提供一个each方法.我真的不明白为什么这样做就是让可枚举方法工作.

另外,我不明白为什么我不需要调用Each方法,请善待我刚刚开始学习的人

class List 
  include Enumerable
  
  def initialize (*list)
    @list = *list
  end

  def each(&block)
    @list.each(&block)
  end
end

Mylist = List.new(1,2,3,4,5)

puts Mylist.any? {|num| num>2} 

我计划使用一些可枚举方法创建我自己的可枚举模块,我认为理解这个概念将有助于我这样做.

推荐答案

让我们首先定义一些包含Enumerable模块的类的实例.

require 'set'

arr = [1, 2, 3]
hsh = { 1=>2, 2=>3, 3=>4 }
rng = (1..3).my_map { |n| n**2 }
set = (1..3).to_set

假设一个可枚举的方法定义如下.

module Enumerable
  def reverse_em
    a = []
    each { |e| a.unshift(e) }
    a
  end
end

然后我们可以写道:

arr.reverse_em #=> [3, 2, 1]
hsh.reverse_em #=> [[:c, 3], [:b, 2], [:a, 1]]
rng.reverse_em #=> [3, 2, 1]
set.reverse_em #=> [3, 2, 1]

如您所见,四个不同类的实例使用单个Enumerable方法.与为四个类中的每一个定义reverse_em相比,这显然是一个更好的设计构造.

为了实现该功能,ArrayHashRangeSet(以及其他核心类)的每个类定义必须具有语句include Enumerable,并且必须包含返回枚举器(Array#eachHash#eachRange#eachSet#each)的实例方法each.

请注意,我的方法reverse_em返回一个数组,而不考虑接收方的类.即使不是所有的Emumerable个方法,也有很多个方法就是这样.

如果用户的定制类可以通过在类定义中包括语句include Enumerable和返回枚举器的实例方法each来利用Enumerable模块中的所有方法.请注意,有几个Enumerable个方法依赖于类要提供的each以外的方法.


现在让我们来看第二个例子,其中Enumerable方法必须考虑到传递块的可能性.具体地说,让我们考虑一下Enumerable#map是如何编码的.

module Enumerable
  def my_map
    return each unless block_given?
    a = []
    each { |e| a << yield(e) }
    a
  end
end

首先,如果没有传递任何块,则返回枚举器,该枚举器简单地枚举接收器的元素(与Enumerable#map一样).

arr.my_map #=> #<Enumerator: [1, 2, 3]:each>
hsh.my_map #=> #<Enumerator: {1=>2, 2=>3, 3=>4}:each>
rng.my_map #=> #<Enumerator: 1..3:each>
set.my_map #=> #<Enumerator: #<Set: {1, 2, 3}>:each>

现在假设通过了一个块.

arr.my_map { |e| 2*e }   #=> [2, 4, 6]
hsh.my_map { |k,v| k*v } #=> [2, 6, 12]
rng.my_map { |n| n**2 }  #=> [1, 4, 9]
set.my_map { |n| n**2 }  #=> [1, 4, 9]   

Ruby相关问答推荐

扫描不带空格的字符串中的单词

Ruby PKCS7:添加;\r〃;字节正在 destruct 解密

Ruby 的 .() 运算符是如何工作的?

如何在加载文件时禁用重新定义常量的警告

获取字符串中的最后一个字符

如何在 Ruby 中初始化 Hash 中的数组

Ruby 中的 Fail vs. raise:我们真的应该相信风格指南吗?

在 Ruby 中创建数字、字符串、数组或哈希的 md5 哈希

C# ?? Ruby 中的运算符?

Rails - create and create!

group_by 在 rails by 2 或更多属性

如何设置方法测试中使用的私有实例变量?

如何将哈希键转换为方法名称?

如何在Ruby中获取给定月份的天数,占年份?

有条件的数组的第一个元素

工厂女孩 - 目的是什么?

在 Ruby 中,获取数组中最大值的索引的最简洁方法是什么?

为什么在 ruby​​ 中动态创建大量符号不是一个好主意(对于 2.2 之前的版本)?

查找两个数组的共同点

如何使用 Ruby 删除回车?