本文来自依云's Blog,转载请注明。
今天看 Matz 的《Ruby编程指南》,遇到一个被称为「flip-flop」的奇特表达式:
在一个由条件式或循环所构成的上下文中,一个 flip-flop 由两个通过
..
操作符相连的布尔表达式构成。除非其左侧表达式为 true,否则一个 flip-flop 表达式就是 false,而且在左侧表达式为 true 之前,它的值都会是 false。一旦该表达式为 true ,那么它就会“flips”到一个持久的 true 状态。它会保持该状态,而且对其后续的求值也返回 true,直到其右侧表达式成为 true 为止。如果其右侧表达式为 true 了,那么该 flip-flop 就会“flops”回一个持久的false状态,对其后续的求值也返回false,直到其左侧表达式再次成为 true 为止。[...]
Flip-flop 是一个非常晦涩的 Ruby 特性,因此最好不要在你的代码中使用它。但是它们并不是 Ruby 所独有的,Ruby 从 Perl 那里继承了这个特性,而 Perl 则从 Unix 的文本处理工具 sed 和 awk 那里继承了这个特性(注4)。Flip-flop 的初衷是在一个开始模式和一个结束模式之间匹配一个文本文件的行,而且这仍然是使用它们的有效方式。下面的这个简单的 Ruby 程序展示了一个 flip-flop,它逐行地从一个文本文件中读取内容,打印出含有“TODO”的行。它会不断地打印文本行,直到读入一个空行为止:
ARGF.each do |line| # For each line of standard in or of named files print line if line=~/TODO/..line=~/^$/ # Print lines when flip-flop is true end
作者还说很难正式地描述一个 flip-flop 的精确行为
。但我不这么认为。
我想到了学习数字电路时遇到的各种触发器,于是乎,反复读了几次以上描述确定了 flip-flop 的行为到底如何后,列出了它的真值表,其中 A、B 为点两边的表达式的值(输入),Q 为其内部状态,Qn 就是 Qnext。
A B Q Qn 0 0 0 0 0 0 1 1 0 1 0 0 0 1 1 0 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1 0
然后和那些触发器的真值表对照,赫然发现它就是JK 触发器——
J K Q Qn 0 0 0 0 0 0 1 1 0 1 X 0 1 0 X 1 1 1 0 1 1 1 1 0
看来 Matz 没学过数字电路 ;-)
PS: flip-flop 在电子电路中就是「触发器」的意思。。。
Mar 25, 2012 11:26:46 AM
唉,我那时候数电没学好啊。。。
Mar 26, 2012 08:13:42 PM
用浅显的话和例子来解释清楚一个东西的叫大师,用艰深的东西一解释一个东西,则可能是作者无力表述或者想故意卖弄。也许作者只是不喜欢卖弄而矣。
Mar 26, 2012 08:33:57 PM
JK触发器是什么? 我学过数字电路,还及格了,但也不知道啊。
Mar 26, 2012 09:10:44 PM
自己看维基百科去。。。
Mar 27, 2012 04:32:33 PM
你这是用的哪种字体啊?
Mar 27, 2012 04:47:45 PM
哪里的字体?有什么问题吗?
Mar 28, 2012 03:07:19 PM
我发现我的字体大小间距都不一样,乱七八糟的。。。
Mar 28, 2012 07:26:47 PM
我没发现呢。
Mar 29, 2012 01:03:18 PM
呃,那估计是浏览器的问题了
Nov 27, 2015 11:01:07 PM
我一直没有理解这个保存状态的“变量”作用域在那里,搞得现在只敢在闭包里用了
另,perl 的ff操作符还有三个点的, 很牛吧