塊是可選的許多Ruby方法。當沒有給出塊時,通常會返回枚舉器。至少有幾個原因可能需要統計員。
#1使用枚舉數與類Enumerator中的方法。
下面是一個例子。假設你想用字符串替換字母的大小寫。一種傳統的方法是:
"oh happy day".each_char.with_index.map { |c,i| i.odd? ? c.upcase : c.downcase }.join
#=> "oH HaPpY DaY"
,但你可以代替寫:
enum = [:odd, :even].cycle
"oh happy day".each_char.map { |c| enum.next==:odd ? c.upcase : c.downcase }.join
或許
enum = [:upcase, :downcase].cycle
"oh happy day".each_char.map { |c| c.send(enum.next) }.join
見Array#cycle和Enumerator#next的文檔。
#2統計員鏈方法
在我上面的第一個例子中,我寫道:
"oh happy day".each_char.with_index.map...
如果您檢查String#each_char的文檔和Enumerator#with_index你會看到,這兩種方法可以使用或不使用塊。在這裏他們都沒有使用塊。這使得三種方法成爲鏈接。
研究下面的返回值。
enum0 = "oh happy day".each_char
#=> #<Enumerator: "oh happy day":each_char>
enum1 = enum0.with_index
#=> #<Enumerator: #<Enumerator: "oh happy day":each_char>:with_index>
enum2 = enum1.map
#=> #<Enumerator: #<Enumerator: #<Enumerator:
# "oh happy day":each_char>:with_index>:map>
你可能要考慮的enum1
和enum2
爲「化合物」統計員。
您展示的返回值:
[nil, false, true].reject
是:
#=> [nil, false, true]
但是這是不正確的。返回值是:
#<Enumerator: [nil, false, true]:reject>
如果我們寫:
enum = [nil, false, true].reject
則:
enum.each { |e| e }
#=> [nil, false]
(其中,因爲紅寶石V2.3,我們可以寫enum.reject(&:itself)
)。這使用方法Enumerator#each,導致enum
調用Array#each,因爲reject
的接收方是類Array
的實例。
它返回[Enumerator](http://ruby-doc.org/core-2.1.5/Enumerator.html) – fl00r
在我的irb中,''[nil,false,true] .reject =>#',這幾乎可以回答這個問題。 –
不帶塊的選擇返回一個枚舉器,就像文檔說的一樣;我不知道你爲什麼期望它不是原始數組以外的任何東西。我不明白爲什麼沒有拒絕標準的「拒絕」會是原始數組以外的任何東西 - 如果沒有理由拒絕某個元素,爲什麼它會成爲「緊湊」? –