为什么带有无效参数的范围有时不会导致参数错误?

yar*_*aru 9 ruby exception range argument-error ruby-1.9.3

以下代码导致参数错误:

n = 15
(n % 4 == 0)..(n % 3 == 0)
# => bad value for range (ArgumentError)
Run Code Online (Sandbox Code Playgroud)

我认为是因为它评估为:

false..true
Run Code Online (Sandbox Code Playgroud)

并且在范围中使用不同类型的类:TrueClassFalseClass.但是,以下代码不会引发错误.这是为什么?不Enumerable#collect抓住它?

(11..20).collect { |i| (i % 4 == 0)..(i % 3 == 0) ? i : nil }
# => no error
Run Code Online (Sandbox Code Playgroud)

稍后添加: 如果fcn返回15,则仅评估范围的前半部分

def fcn(x)
  puts x
  15
end

if  (fcn(1) % 4 == 0)..(fcn(2) % 3 == 0); end
# => 1
Run Code Online (Sandbox Code Playgroud)

但如果我们将返回值更改为16,那么输入将是

# => 1
# => 2
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为在这种情况下表达式的计算结果为

true..false
Run Code Online (Sandbox Code Playgroud)

根据sawa的回答,这种范围是无效的.

那么在第一种情况下(def的返回值为15),我们只有部分范围没有结束部分?真奇怪:)

Sim*_*tsa 8

在Ruby中if start..finish是一个触发器,一种用于编写快速和模糊脚本的特殊语法.它通常用于循环:

while input = gets
  puts "Processing #{input.inspect}" if input =~ /start/ .. input =~ /end/
end
Run Code Online (Sandbox Code Playgroud)

当第一个条件为真时,在每次连续执行时都认为整个条件为真,直到第二个条件的计算结果为真.您可以使用上面的脚本来获得想法.这是我的输入和输出:

foo
start
Processing "start\n"
foo
Processing "foo\n"
bar
Processing "bar\n"
end
Processing "end\n"
foo
bar
start
Processing "start\n"
Run Code Online (Sandbox Code Playgroud)

请注意,如果条件未启动,Ruby不会评估完成条件,因为这样做无用.

虽然在循环之外使用它没有多大意义,但Ruby并没有限制它.

>> if nil..raise; :nothing_gonna_happen; end
=> nil
Run Code Online (Sandbox Code Playgroud)