ОП написала
Мені здається дивним, що вищезгадана конструкція не дає очікуваного результату. У чому причина цього? Які ситуації, коли така поведінка розумна?
не "Чи можна це зробити?" але відповісти на запитання, яке не було задано, перш ніж перейти до питання, яке насправді було задано:
$ 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 створює цілий масив, downto очевидно буде більш ефективним. Той факт, що мовний дизайнер навіть міг розглянути можливість реалізувати такі речі, як такі, що є відповіддю на відповідь на власне запитання.
Щоб відповісти на запитання, як насправді задали ...
Причина в тому, що Рубі - нескінченно дивна мова. Деякі сюрпризи приємні, але багато поведінки, яка прямо порушена. Навіть якщо деякі з наведених нижче прикладів виправлені новішими випусками, інших є багато, і вони залишаються як обвинувачення у менталітеті оригінального дизайну:
nil.to_s
.to_s
.inspect
призводить до "", але
nil.to_s
# .to_s # Don't want this one for now
.inspect
призводить до
syntax error, unexpected '.', expecting end-of-input
.inspect
^
Ви, ймовірно, очікували, що << і push буде однаковим для додавання до масивів, але
a = []
a << *[:A, :B] # is illegal but
a.push *[:A, :B] # isn't.
Ви, напевно, очікували, що "grep" поводитиметься як його еквівалент командного рядка Unix, але він, незважаючи на свою назву, === відповідає не = ~.
$ echo foo | grep .
foo
$ ruby -le 'p ["foo"].grep(".")'
[]
Різноманітні методи є несподівано псевдонімами один для одного, тому вам доведеться вивчити кілька імен для однієї і тієї ж речі - наприклад, find
і detect
- навіть якщо ви любите більшість розробників і використовуєте лише той чи інший. Те ж саме стосується size
, count
і length
для класів , які визначають кожен по- різному, або не визначають один або два на всіх , крім.
Якщо хтось не реалізував щось інше - як основний метод tap
був перероблений у різних бібліотеках автоматизації, щоб щось натиснути на екрані. Успіхів дізнатися, що відбувається, особливо якщо якийсь модуль, який вимагає якийсь інший модуль, маніпулює ще одним модулем, щоб зробити щось без документації.
Об'єкт змінної середовища, ENV не підтримує "злиття", тому вам доведеться писати
ENV.to_h.merge('a': '1')
Як бонус ви навіть можете переосмислити свої чи чужі константи, якщо передумаєте, якими вони повинні бути.