OP yazdı
Yukarıdaki yapının beklenen sonucu vermemesi bana garip geliyor. Bunun sebebi nedir? Bu davranışın makul olduğu durumlar nelerdir?
"Yapılabilir mi?" ama aslında sorulan soruya gelmeden önce sorulmayan soruyu cevaplamak için:
$ irb
2.1.5 :001 > (0..4)
=> 0..4
2.1.5 :002 > (0..4).each { |i| puts i }
0
1
2
3
4
=> 0..4
2.1.5 :003 > (4..0).each { |i| puts i }
=> 4..0
2.1.5 :007 > (0..4).reverse_each { |i| puts i }
4
3
2
1
0
=> 0..4
2.1.5 :009 > 4.downto(0).each { |i| puts i }
4
3
2
1
0
=> 4
Reverse_each'in tüm bir diziyi oluşturduğu iddia edildiğinden, aşağıya doğru açıkça daha verimli olacaktır. Bir dil tasarımcısının bu tür şeyleri uygulamayı bile düşünebilmesi, sorulduğu gibi asıl sorunun cevabına bağlanır.
Soruyu gerçekten sorulduğu gibi cevaplamak için ...
Bunun nedeni, Ruby'nin sonsuz derecede şaşırtıcı bir dil olmasıdır. Bazı sürprizler hoştur, ancak tamamen bozulmuş birçok davranış vardır. Aşağıdaki örneklerden bazıları daha yeni sürümlerle düzeltilse bile, başka pek çok örnek var ve bunlar orijinal tasarımın zihniyetine yönelik suçlamalar olarak kalıyor:
nil.to_s
.to_s
.inspect
"" ile sonuçlanır ancak
nil.to_s
# .to_s # Don't want this one for now
.inspect
sonuçlanır
syntax error, unexpected '.', expecting end-of-input
.inspect
^
Muhtemelen << ve dizilere ekleme için aynı olmasını beklersiniz, ancak
a = []
a << *[:A, :B] # is illegal but
a.push *[:A, :B] # isn't.
Muhtemelen 'grep'in Unix komut satırı eşdeğeri gibi davranmasını beklersiniz, ancak ismine rağmen === eşleşmeyen = ~ ile eşleşmez.
$ echo foo | grep .
foo
$ ruby -le 'p ["foo"].grep(".")'
[]
Çeşitli yöntemler beklenmedik şekilde birbirlerinin takma adlarıdır, bu nedenle aynı şey için birden fazla ad öğrenmeniz gerekir - örneğin find
ve detect
- çoğu geliştiriciyi sevseniz ve yalnızca birini veya diğerini kullansanız bile. Hemen hemen aynı için de geçerlidir size
, count
ve length
farklı şekilde tanımlamak ya da hiç bir ya da iki tanımlamaz sınıfları haricinde.
Birisi başka bir şey uygulamadıysa - tap
ekrandaki bir şeye basmak için çeşitli otomasyon kitaplıklarında çekirdek yöntem yeniden tanımlanmış gibi. Neler olup bittiğini öğrenmede iyi şanslar, özellikle de başka bir modülün gerektirdiği bazı modül, belgelenmemiş bir şey yapmak için başka bir modül başlattıysa.
Ortam değişkeni nesnesi, ENV 'birleştirmeyi' desteklemiyor, bu yüzden yazmanız gerekiyor
ENV.to_h.merge('a': '1')
Bonus olarak, ne olması gerektiği konusunda fikrinizi değiştirirseniz, kendinizin veya bir başkasının sabitlerini yeniden tanımlayabilirsiniz.