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



以下代码导致参数错误:

n = 15
(n % 4 == 0)..(n % 3 == 0)
# => bad value for range (ArgumentError)

我认为这是因为它评估为:

false..true

并且在范围内使用不同类型的类:CCD_ 1和CCD_。但是,以下代码不会引发错误。为什么?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),我们只有没有结束部分的部分范围?这太奇怪了:)

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

while input = gets
  puts "Processing #{input.inspect}" if input =~ /start/ .. input =~ /end/
end

当第一个条件为true时,在每次连续执行时,整个条件都被视为true,直到第二个条件评估为true。你可以用上面的脚本来获得这个想法。这是我的输入&输出:

foo
start
Processing "startn"
foo
Processing "foon"
bar
Processing "barn"
end
Processing "endn"
foo
bar
start
Processing "startn"

注意,如果条件没有启动,Ruby就不会评估完成条件,因为这样做毫无用处

尽管在循环之外使用这个没有多大意义,但Ruby并没有限制这一点。

>> if nil..raise; :nothing_gonna_happen; end
=> nil

首先,请注意以下有效和无效的文字:

true..true # => valid
false..false # => valid
true..false # => invalid
false..true # => invalid

因此,问题归结为当嵌入到循环条件中时,为什么计算为false..truetrue..false的表达式变得有效。根据文档,循环中的范围文字条件实际上并不能创建范围。它有一种特殊的含义,类似于sed和awk。也就是说,范围开始的真值启动循环,范围结束的真值终止循环。

相关内容

  • 没有找到相关文章

最新更新