更改ruby中的方法行为

时间:2012-08-06 14:00:41

标签: ruby mixins

以下是来自红宝石镐书的代码示例:

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在某个时候调用它但是不明白它为什么这样做,以及我如何在我的代码中预测或模拟这种行为。

谢谢!

3 个答案:

答案 0 :(得分:1)

inject的调用实际上会调用eachinject的工作方式是使用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方法进行补贴(当然,除非你希望所有其他方法都改变。)