Ruby 为什么触发器操作符包含第二个条件?

Ruby 为什么触发器操作符包含第二个条件?,ruby,flip-flop,Ruby,Flip Flop,以下代码正在使用触发器运算符 (1..10).each {|x| print "#{x}," if x==3..x==5 } 为什么结果是3,4,5 我想应该是3,4 如教程中所述,当x==3时,此表达式变为真,并持续到x==5。如果“5”的计算结果为false,如何打印它?有人能帮我澄清一下吗?您是在寻找独家产品吗?您可以使用三个点和cover?方法 (1..10).each { |x| print "#{x}," if (3...5).cover?(x) } 在你的例子中,它打印3,4,

以下代码正在使用触发器运算符

(1..10).each {|x| print "#{x}," if x==3..x==5 }
为什么结果是
3,4,5

我想应该是
3,4


如教程中所述,当
x==3
时,此表达式变为真,并持续到
x==5
。如果“5”的计算结果为false,如何打印它?有人能帮我澄清一下吗?

您是在寻找独家产品吗?您可以使用三个点和
cover?
方法

(1..10).each { |x| print "#{x}," if (3...5).cover?(x) }

在你的例子中,它打印3,4,5的原因是因为它说如果x在3到5之间,就打印它

为了澄清@MurifoX的评论,触发器在
x==5
之前为真,因此在
x==5
时为真,但在此后每次计算表达式时为假。因此,您仍然可以看到5正在打印。

来自“Ruby编程语言”的重要链接是:

当。。而且。。。运算符用于条件语句中,如if语句,或 在循环中,例如while循环(有关条件和循环的更多信息,请参阅第5章), 它们不创建范围对象。相反,它们创建了一种特殊的布尔值 表达式称为触发器。触发器表达式的计算结果为true或false,与 比较表达式和相等表达式可以。关于一个孩子的不同寻常的事情 然而,触发器表达式的值取决于先前evalu的值- 不公平。这意味着触发器表达式具有与其关联的状态;它必须 记住有关以前评估的信息。因为它有状态,你会 期望触发器是某种类型的对象。但它不是——它是一个Ruby表达式,而且 Ruby解释器将所需的状态(仅一个布尔值)存储在表达式的内部解析表示中

在这种背景下,考虑下面代码中的触发器。注意 第一。。在代码中,创建一个范围对象。第二个创建触发器 表达方式:

(1..10).each {|x| print x if x==3..x==5 }
触发器由两个与..连接的布尔表达式组成。。接线员,在 条件或循环的上下文。触发器表达式为false,除非 lefthand表达式的计算结果为true。一旦这句话成为事实,前- 按“翻转”到持续的真实状态。它仍处于该状态,随后 求值返回true,直到右侧表达式求值为true。什么时候 发生这种情况时,触发器会“跳转”回一个持续的错误状态。后续评价 返回false,直到左手表达式再次变为true。 在代码示例中,对x值从1到1重复计算触发器 10它以false状态开始,当x为1和2时计算为false。什么时候 x==3,触发器将翻转为true并返回true。当x为时,它继续返回true 4和5。然而,当x==5时,触发器将返回false,并返回false作为参数 x的剩余值。结果是该代码打印345


或触发器是从Perl继承的,Perl是从AWK和*nix中的sed获得的。它非常强大,但在您的特定用途中,它相当模糊,对于您想要的逻辑来说,不是一个好的选择,尤其是在Ruby中。而是使用:

(1..10).each {|x| puts x if (3..5) === x }
哪些产出:

3
4
5
Agatha
Ahmed
Ahmet
Wade
Walt
Walter
Warren
Wayne
Wendell
Amanda
Amarth
Amedeo
Ami
Amigo
Amir
Amos
Amy
Anatole
Wade
Walt
Walter
Warren
Wayne
Wendell
也就是说,当您需要从文件中提取一系列行时,它的功能非常强大:

File.foreach('/usr/share/dict/propernames') { |li| puts li if ($. == 5 .. $. == 7) }
哪些产出:

3
4
5
Agatha
Ahmed
Ahmet
Wade
Walt
Walter
Warren
Wayne
Wendell
Amanda
Amarth
Amedeo
Ami
Amigo
Amir
Amos
Amy
Anatole
Wade
Walt
Walter
Warren
Wayne
Wendell
Perl允许只使用当前读取行(AKA)的行号来实现更简洁的表达式,但Ruby不支持这一点

还可以选择使用正则表达式,其行为与前面的比较类似:

File.foreach('/usr/share/dict/propernames') { |li| puts li if (li[/^Wa/] .. li[/^We/]) }
哪些产出:

3
4
5
Agatha
Ahmed
Ahmet
Wade
Walt
Walter
Warren
Wayne
Wendell
Amanda
Amarth
Amedeo
Ami
Amigo
Amir
Amos
Amy
Anatole
Wade
Walt
Walter
Warren
Wayne
Wendell
因为正则表达式可以工作,所以可以创建一个复杂的模式来根据匹配从文件中检索行。作为第一个模式触发器,然后是第二个模式触发器,捕捉线。如果在文件的后面,另一行触发第一个模式,则将再次进行捕获,直到第二个模式匹配为止。它的功能非常强大:

File.foreach('/usr/share/dict/propernames') { |li| puts li if (
    li[/^Am/] .. li[/^An/] or
    li[/^Wa/] .. li[/^We/]
  )
}
哪些产出:

3
4
5
Agatha
Ahmed
Ahmet
Wade
Walt
Walter
Warren
Wayne
Wendell
Amanda
Amarth
Amedeo
Ami
Amigo
Amir
Amos
Amy
Anatole
Wade
Walt
Walter
Warren
Wayne
Wendell
或者,对于我们默默无闻的讲代码的朋友:

File.foreach('/usr/share/dict/propernames') { |li| puts li if (li[/^(?:Am|Wa)/] .. li[/^(?:An|We)/]) }
我找到一段代码来说明触发器是如何工作的(就在这段代码出现的同一本书中,希望它能帮助像我这样有同样问题的人)


触发器表达式的计算结果为true或false,就像比较表达式和相等表达式一样。 然而,触发器表达式的一个不同寻常之处在于,它的值取决于以前求值的值。这意味着触发器表达式具有与其关联的状态;它必须记住有关以前评估的信息。因为它有状态,你会 期望触发器是某种类型的对象。但它不是——它是一个Ruby表达式,而且 Ruby解释器将所需的状态(仅一个布尔值)存储在表达式的内部解析表示中。考虑到这个背景,考虑下面代码中的触发器。请注意,代码中的第一个“.”创建了一个范围对象。第二个创建触发器表达式:

(1..10).each {|x| print x if x==3..x==5 }
触发器由两个与..连接的布尔表达式组成。。接线员,在 条件或循环的上下文。触发器表达式为false,除非 lefthand表达式的计算结果为true。一旦该表达式变为真,表达式将“翻转”为持久的真状态。它仍处于该状态,随后 求值返回true,直到右侧表达式求值为true。什么时候 发生这种情况时,触发器会“跳转”回一个持续的错误状态。后续评价 返回false,直到左手表达式再次变为true。 在代码示例中,对x值从1到1重复计算触发器 10它从错误的状态开始