1

これがルビーつるはしの本からのコードサンプルです:

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はある時点でそれを呼び出していると思いますが、なぜそれを行っているのか、そしてコードでこの動作を予測またはエミュレートする方法がわかりません。

ありがとう!

4

3 に答える 3

1

toを呼び出すと、inject実際には。が呼び出されeachます。動作する方法は、 usinginjectのすべての要素を調べ、渡された演算子をとに次の値に適用し、結果をに格納することです。呼び出し全体の結果は、最終的にのの値です。ここでドキュメントを見ることができます。Enumerableeachmemomemomemo

于 2012-08-06T14:03:27.613 に答える
1

このVowelFinderクラスは、多くのrubyイテレータメソッドを取得するために含めることができるモジュールに必須のプロトコルを実装します。http: //apidock.com/ruby/EnumerableEnumerable

Enumerableミックスインは、コレクションクラスにいくつかのトラバーサルメソッドと検索メソッドを提供し、ソートする機能を備えています。クラスは、コレクションの連続するメンバーを生成するメソッドをそれぞれ提供する必要があります。Enumerable#max、#min、または#sortを使用する場合、これらのメソッドはコレクションのメンバー間の順序に依存するため、コレクション内のオブジェクトも意味のある<=>演算子を実装する必要があります。

于 2012-08-06T14:09:30.293 に答える
1

injectが実際に各メソッドを呼び出すのは正しいことです。これが発生する理由は、injectが実際に各メソッドを内部で使用するためです。実際、Enumerableメソッドが.eachメソッドを使用する場合は多くあります。#map、#select、#rejectのように。

この理由は、.eachが列挙可能なオブジェクトでのループを可能にする実際のメソッドであるためです。他の方法は、開発者にとって物事が簡単になるようにするためのものであり、どこでも.eachを使用する必要はありません。.eachを使用して上記のコードを記述しなければならないことを想像してみてください。難しいことではありませんが、vf.inject(:+)の方が間違いなく簡単です。収集またはマップの場合も同様です。

そして、コードを繰り返さずにこれを実装する(Rubyで行われるように)最良の方法は、コードの重複がなく、#map、#collect、または#injectのそれぞれがEnumerableをトラバースする必要がないため、他のメソッドで#eachを呼び出すことです。別の方法でオブジェクトします。

一般的に、私は#eachの使用を避け、仕事を簡単にする方法は他にもたくさんあります。配列コレクションを変更する場合は、#eachメソッドにマネーパッチを適用しないことをお勧めします(もちろん、他のすべてのメソッドも変更する必要がある場合を除きます)。

于 2012-08-06T14:29:00.127 に答える