Следующий код вызывает ошибку аргумента:
n = 15
(n % 4 == 0)..(n % 3 == 0)
# => bad value for range (ArgumentError)
что я думаю, потому что он оценивает:
false..true
и в диапазоне используются разные типы классов: TrueClass
и FalseClass
. Однако следующий код не вызывает ошибку. Это почему? Enumerable#collect
ловит?
(11..20).collect { |i| (i % 4 == 0)..(i % 3 == 0) ? i : nil }
# => no error
Добавлено позже: если fcn возвращает 15, то оценивается только первая половина диапазона
def fcn(x)
puts x
15
end
if (fcn(1) % 4 == 0)..(fcn(2) % 3 == 0); end
# => 1
но если мы изменим возвращаемое значение на 16, тогда ввод будет
# => 1
# => 2
Странно, потому что в этом случае выражение оценивается как
true..false
И такой диапазон недействителен в соответствии с ответом sawa ниже.
Тогда в первом случае (с возвращаемым значением def 15) у нас есть только частичный диапазон без конечной части? Это так странно :)
(true..false); 1
работает, аx = (true..false); 1
нет? кстати, этого не происходит с Ruby 1.8.7. - person tokland   schedule 12.09.2012