El OP escribió
Me parece extraño que la construcción anterior no produzca el resultado esperado. ¿Cuál es la razón de eso? ¿Cuáles son las situaciones en las que este comportamiento es razonable?
no '¿Se puede hacer?' pero para responder la pregunta que no se hizo antes de llegar a la pregunta que realmente se hizo:
$ 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
Dado que se afirma que reverse_each crea una matriz completa, es evidente que downto será más eficiente. El hecho de que un diseñador de idiomas pueda incluso considerar implementar cosas como esa se relaciona un poco con la respuesta a la pregunta real tal como se le preguntó.
Para responder a la pregunta como se hizo realmente ...
La razón es que Ruby es un lenguaje infinitamente sorprendente. Algunas sorpresas son agradables, pero hay muchos comportamientos que están rotos. Incluso si algunos de estos ejemplos siguientes se corrigen con versiones más recientes, hay muchos otros y permanecen como acusaciones en la mentalidad del diseño original:
nil.to_s
.to_s
.inspect
da como resultado "" pero
nil.to_s
# .to_s # Don't want this one for now
.inspect
resultados en
syntax error, unexpected '.', expecting end-of-input
.inspect
^
Probablemente esperaría que << y push sea lo mismo para agregar a matrices, pero
a = []
a << *[:A, :B] # is illegal but
a.push *[:A, :B] # isn't.
Probablemente esperaría que 'grep' se comporte como su equivalente en la línea de comandos de Unix, pero no coincide === con = ~, a pesar de su nombre.
$ echo foo | grep .
foo
$ ruby -le 'p ["foo"].grep(".")'
[]
Varios métodos tienen alias inesperadamente entre sí, por lo que debe aprender varios nombres para lo mismo, por ejemplo, find
y detect
, incluso si le gusta la mayoría de los desarrolladores y solo usa uno u otro. Lo mismo ocurre con size
, count
y length
, excepto para las clases que definen cada una de manera diferente, o que no definen una o dos en absoluto.
A menos que alguien haya implementado algo más, como que el método principal tap
se haya redefinido en varias bibliotecas de automatización para presionar algo en la pantalla. Buena suerte averiguando lo que está pasando, especialmente si algún módulo requerido por otro módulo ha engañado a otro módulo para hacer algo indocumentado.
El objeto de la variable de entorno, ENV no admite 'fusionar', por lo que debe escribir
ENV.to_h.merge('a': '1')
Como beneficio adicional, incluso puede redefinir sus constantes o las de otra persona si cambia de opinión sobre lo que deberían ser.