2009-09-03 5 views
4

Quelqu'un peut-il nous éclairer sur les raisons de ce qui suit?Comportement inattendu de la gamme Ruby

irb(main):001:0> r = '1'..'30' 
=> "1".."30" 
irb(main):002:0> r.each do |i| 
irb(main):003:1* puts "#{i} : #{r.include?(i)}" 
irb(main):004:1> end 
1 : true 
2 : true 
3 : true 
4 : false 
5 : false 
6 : false 
7 : false 
8 : false 
9 : false 
10 : true 
... 
(snip.. the String-numbers here evaluate to true) 
... 
29 : true 
30 : true 
=> "1".."30" 

J'attends ci-dessus pour être tous true s. Si je fais ce qui suit:

irb(main):005:0> r.to_a.each do |i| 
irb(main):006:1* puts "#{i} : #{r.to_a.include?(i)}" 
irb(main):007:1> end 
1 : true 
2 : true 
... 
(snip.. the String-numbers here evaluate to true) 
... 
29 : true 
30 : true 
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", " 
15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28 
", "29", "30"] 

alors j'obtiens ce que j'attendais. Ai-je manqué quelque chose avec la façon dont les gammes fonctionnent ou pourrait-il s'agir d'un bug (probablement l'ancien)? Mon mauvais à l'avance si c'est une question noob. La citation hard/soft ne fait pas de différence, et le même problème se produit avec des plages de nombres sous forme de chaîne pour des valeurs autres que 1 à 30.

Répondre

9

Ceci est une bizarrerie de la façon dont les plages fonctionnent dans Ruby. Les objets sont générés en appelant de manière répétée succ, mais l'appartenance est déterminée par x >= r.start && x <= r.end. Les chaînes de Ruby n'ont pas de comportement spécial pour les numéros de commande - '4' est supérieur à '10' car '4' est supérieur à '1'. Ainsi, tous les nombres à un chiffre qui sont supérieurs au premier chiffre de la valeur finale n'apparaîtront pas dans la plage.

+0

Fait sens. Merci – maksim