2009-09-03 49 views
4

任何人都可以對以下情況做出解釋嗎?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" 

我期望以上全部都是true s。如果我這樣做:

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"] 

然後我得到我的預期。我是否錯過了範圍的工作方式,或者這可能是一個錯誤(可能是前者)?如果這是一個noob問題,我會提前做好。硬/軟引用沒有什麼區別,並且對於1到30之間的值,字符串形式的數字範圍也會發生同樣的問題。

回答

9

這是Ruby範圍工作的一個怪癖。通過反覆調用succ生成對象,但成員資格由x >= r.start && x <= r.end確定。 Ruby中的字符串對於排序數字沒有特殊的行爲 - '4'大於'10',因爲'4'大於'1'。因此,高於結束值第一位的任何一位數字都不會顯示在範圍內。

+0

有道理。謝謝 – maksim 2009-09-03 22:48:57