以下是来自红宝石镐书的代码示例:
Class VowelFinder
include Enumerable
def initialize(string)
@string = string
end
def each
@string.scan(/[aeiou]/] do |vowel|
yield vowel
end
end
end
vf = VowelFinder.new("the quick brown fox jumped")
vf.inject(:+) # => 'euiooue'
我很难理解修改后的“每种”方法发挥作用的地方?我假设inject在某个时候调用它但是不明白它为什么这样做,以及我如何在我的代码中预测或模拟这种行为。
谢谢!
答案 0 :(得分:1)
对inject
的调用实际上会调用each
。 inject
的工作方式是使用Enumerable
遍历each
的所有元素,将传递的运算符应用于memo
和下一个值并将结果存回进入memo
。整个调用的结果最后是memo
的值。您可以在here。
答案 1 :(得分:1)
VowelFinder
类实现了协议,它是Enumerable
模块必需的,您可以包含该模块以获得大量ruby 迭代器方法:http://apidock.com/ruby/Enumerable
Enumerable mixin提供了几个集合类 遍历和搜索方法,并具有排序的能力。该 class必须提供一个方法,它产生连续的成员 集合。如果使用了Enumerable#max,#min或#sort,则为对象 在集合中还必须实现一个有意义的< =>运营商,作为 这些方法依赖于集合成员之间的排序。
答案 2 :(得分:1)
你是正确的,实际上注入每个方法,并且发生这种情况的原因是因为注入实际上在内部使用每个方法。事实上,如果Enumerable方法使用.each方法,那就很多了;比如#map,#select,#reject。
原因是.each是允许在Enumerable Object中循环的实际方法。其他方法只是让我们开发人员变得容易,而且我们不必在任何地方使用.each。想象一下,必须使用.each编写上面的代码。这不会很难,但vf.inject(:+)肯定更容易。收集或地图也是如此。
实现这一点的最佳方法(如在Ruby中完成)而不重复代码是让另一个方法调用#each,因为没有代码重复,#map或#collect或#inject中的每一个都不需要以不同方式遍历可枚举对象。
一般来说,我避免使用#each,还有很多其他方法可以让我们的工作更轻松。如果你想修改你的数组集合,建议不要对#each方法进行补贴(当然,除非你希望所有其他方法都改变。)