触发器(又名 f/f)是源自 perl 的有状态运算符。
f/f 运算符隐含在 ruby 的条件语句(if 和三元)中而不是 range 所以 (1..5) 是一个范围但是 (1..5) ?1 : 5 是 af/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
让我们继续阅读令人惊叹的 perl 文章,但使用 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
PS Range 和 Flip/flop 是两个完全不同的运算符,您不应混淆它们。