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

标签 ruby exception range ruby-1.9.3 argument-error

以下代码会导致参数错误:

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

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

false..true

并且范围内使用了不同类型的类:TrueClassFalseClass。但是,以下代码不会引发错误。这是为什么? 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

当第一个条件为真时,整个条件在每次连续执行时都被视为真,直到第二个条件的计算结果为真。你可以玩上面的脚本来理解这个想法。这是我的输入和输出:

foo
start
Processing "start\n"
foo
Processing "foo\n"
bar
Processing "bar\n"
end
Processing "end\n"
foo
bar
start
Processing "start\n"

请注意,如果条件未开始,Ruby 不会评估结束条件,因为这样做毫无用处。

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

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

关于ruby - 为什么带有无效参数的范围有时不会导致参数错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12386172/

相关文章:

ruby - 我如何在纯 Ruby 中实现 Rails 的 before_initialize/before_new 之类的东西?

java - 来自组件的包装异常

arrays - 如何将范围作为数组从 Excel 导入 Word 文档

arrays - 如何将 csv 中的特定元素存储到变量中?

ruby 隐藏控制台

ruby-on-rails - 如何根据多对多相关模型的属性查找记录?

sql - Azure SqlExceptions

php - Laravel 资源 Controller 测试第二次给出 NotFoundHttpException

javascript - safari:获取鼠标指针下的单词

Ruby range.reduce 与哈希累加器