bir blok birçok Ruby yöntemleri için isteğe bağlıdır. Blok verilmediğinde, bir sayım genellikle iade edilir. Bir numaralayıcı isteyebileceğiniz en az birkaç sebep vardır.
# 1 Sayımı, Enumerator sınıfındaki yöntemlerle kullanın.
İşte bir örnek. Dize içindeki harflerin durumunu değiştirmek istediğinizi varsayalım.
"oh happy day".each_char.with_index.map { |c,i| i.odd? ? c.upcase : c.downcase }.join
#=> "oH HaPpY DaY"
ancak bunun yerine yazabilirsiniz: Tek alışılmış şeklidir
enum = [:odd, :even].cycle
"oh happy day".each_char.map { |c| enum.next==:odd ? c.upcase : c.downcase }.join
ya da belki
enum = [:upcase, :downcase].cycle
"oh happy day".each_char.map { |c| c.send(enum.next) }.join
Array#cycle ve Enumerator#next belgelerine bakınız. Zincir yöntemlerine
# 2 Kullanım enumerator'ın yukarıdaki ilk örnekte
yazdım:
"oh happy day".each_char.with_index.map...
Eğer iki yöntem olabileceğini göreceksiniz Enumerator#with_indexString#each_char için dokümanlar incelemek ve varsa bloklu veya bloksuz olarak kullanılır. Burada her ikisi de bloksuz kullanılır. Bu, üç yöntemin zincirleme olmasını sağlar.
Aşağıdakilerde dönüş değerlerini inceleyin.
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>
Sen "bileşik" Enumerator'lar olarak enum1
ve enum2
düşünmek isteyebilirsiniz.
[nil, false, true].reject
olmak:
Sen dönüş değeri göstermek
#=> [nil, false, true]
ama bu doğru değil. biz yazarsanız
#<Enumerator: [nil, false, true]:reject>
: dönüş değeridir sonra
enum = [nil, false, true].reject
:
enum.each { |e| e }
#=> [nil, false]
(ki, Yakut v2.3 beri, biz enum.reject(&:itself)
yazabilirsiniz). Bu, 'u çağırmak için enum
1 nedenine neden olan Enumerator#each yöntemini kullanır; çünkü reject
alıcısı, sınıfın sınıfının bir örneğidir.
[Enumerator] döndürür (http://ruby-doc.org/core-2.1.5/Enumerator.html) – fl00r
irb'm içinde, [nil, false, true] .reject => # reddet. –
Bloksuz seç, tıpkı dokümanlar gibi, bir numaralayıcı döndürür; Orijinal diziden başka bir şey olmasını neden beklediğinden emin değilim. Hiçbir reddetme kriteri olmadan 'reddetmenin' neden orijinal diziden başka bir şey olamayacağını anlamıyorum - bir unsuru reddetmek için hiçbir neden yoksa, neden 'kompakt' olur? –