触发器(又名 f/f)是一个源自 perl 的有状态运算符。
f/f 运算符隐含在 ruby 的条件语句(if 和三元)中,而不是 range
所以 (1..5) 是一个范围但是 (1..5) ? 1 : 5 是 f/f。
f/f 有一个内部状态(真/假),由两个条件组成。
当它的第一个条件评估为真时它会打开(状态变为真),当它的第二个条件评估为真时它会关闭。
两个和三个虚线版本的区别在于
双点在第一个条件评估为真之后立即评估第二个条件,并且
三点没有。
两个虚线版本是这样的:
A..B |
A -> false | State -> false
A -> true, B -> false | State -> true # notice how it checks both conditions
B -> false | State -> true
B -> true | State -> false
A -> false | State -> false
A -> true, B -> true | State -> false
比较一下三个点的版本
A...B
A -> false | State -> false
A -> true | State -> true # three dotted version doesn't check second condition immediately
B -> false | State -> true
B -> true | State -> false
A -> false | State -> false
A -> true | State -> true
让我们继续 amazing perl article,但使用 ruby 中的示例
两个虚线示例:
DATA.each_line do |line|
print "\t" if (line =~ /^start/ .. line =~ /^end/)
print line
end
__END__
First line.
start
Indented line
end
Back to left margin
打印出来:
First line.
start
Indented line
end
Back to left margin
如您所见 - f/f 在第 2 行打开,在第 4 行关闭。
然而,它有一个微妙之处。看看这个:
DATA.each_line do |line|
print "\t" if (line =~ /start/ .. line =~ /end/)
print line
end
__END__
First line.
Indent lines between the start and the end markers
Back to left margin
打印出来:
First line.
Indent lines between the start and the end markers
Back to left margin
它在第 2 行打开并立即关闭。
假设您不想在第一个运算符之后立即检查第二个运算符。
这就是三点 f/f 派上用场的地方。查看下一个示例。
DATA.each_line do |line|
print "\t" if (line =~ /start/ ... line =~ /end/)
print line
end
__END__
First line.
Indent lines between the start and the end markers
So this is indented,
and this is the end of the indented block.
Back to left margin
哪些打印:
First line.
Indent lines between the start and the end markers
So this is indented,
and this is the end of the indented block.
Back to left margin
如您所见,它在第 2 行打开,在第 4 行关闭
现在让我们将它应用到您的示例中
我写了一个小脚本来说明它的行为
def mod(n, i)
result = i % n == 0
puts "#{i} mod #{n} => #{result}"
result
end
(11..20).each { |i|
if (mod(4, i))...(mod(3, i)) # NOTE it's a three dotted version
# NOTE that those puts show previous state, not the current one!
puts true
else
puts false
end
}
两个虚线结果:
11 mod 4 => false
false
12 mod 4 => true
12 mod 3 => true # Notice how it checks both conditions here
true
13 mod 4 => false
false
14 mod 4 => false
false
15 mod 4 => false
false
16 mod 4 => true
16 mod 3 => false
true
17 mod 3 => false
true
18 mod 3 => true
true
19 mod 4 => false
false
20 mod 4 => true
20 mod 3 => false
true
三个点的结果:
11 mod 4 => false
false
12 mod 4 => true
true
13 mod 3 => false
true
14 mod 3 => false
true
15 mod 3 => true # turns OFF here
true
16 mod 4 => true # and turns immediately ON here
true
17 mod 3 => false
true
18 mod 3 => true
true
19 mod 4 => false
false
20 mod 4 => true
true
=> 11..20
附:范围和触发器是两个完全不同的运算符,您不应该混淆它们。