新手问题 关于一个表达式的小疑问

color_huo · 2013年09月07日 · 最后由 wanzicaidi 回复于 2014年01月19日 · 4494 次阅读

该如何理解俩个表达式的结果 print a=(11..20).collect {|i| (i%4==0)..(i%3==0)? i:nil} print "\n" print a=(11..20).collect {|i| (i%4==0)...(i%3==0)? i:nil}

➜ Rubyex ruby test3.rb [nil, 12, nil, nil, nil, 16, 17, 18, nil, 20] [nil, 12, 13, 14, 15, 16, 17, 18, nil, 20]%

不要学习这类杂耍的写法,开发软件不是表演杂技,代码易读性远高于耍技巧

应该是 ruby 的 bug 吧

这是 flip-flop 啊

我觉得至少要学会看懂代码 (就算是一些很蹊跷的代码), 是不是该用也是学会以后再自己判断...

相关讨论:https://www.ruby-forum.com/topic/2713360

来自 perl: http://perldoc.perl.org/perlop.html#Range-Operators

命令行黑客的小刀之一。例如

打印第 3 到 6 行:

ruby -ne 'print if 3..6' < some_text

打印文本文件中从匹配 =begin 的那一行到匹配 =bar 的行:

ruby -ne 'print if /=begin/../=end/' < some_text

用在 rails 中就不太推荐,因为你的队友很可能没用过 perl.

在一个由条件式或循环所构成的上下文中,一个 flip-flop 由两个通过..操作符相连的布尔表达式构成。除非其左侧表达式为 true,否则一个 flip-flop 表达式就是 false,而且在左侧表达式为 true 之前,它的值都会是 false。一旦该表达式为 true,那么它就会“flips”到一个持久的 true 状态。它会保持该状态,而且对其后续的求值也返回 true,直到其右侧表达式成为 true 为止。如果其右侧表达式为 true 了,那么该 flip-flop 就会“flops”回一个持久的 false 状态,对其后续的求值也返回 false,直到其左侧表达式再次成为 true 为止。

ex1:

11, false..false, pass
12, true..true, collect
13, false..false, pass
14, false..false, pass
15, false..false, pass
16, true..false, collect
17, true..false, collect
18, true..true, collect
19, false..false, pass
20, true..false, collect

..和...的区别是,..是当左侧为 true 时,同时根据右侧来决定 flip-flop 的状态是否为 false,...是下次再根据右侧值决定 flip-flop 的状态

ex2:

11, false...false, pass
12, true...true, collect (虽然右边是true,但是这次被忽略)
13, false...false, collect (这里虽然左右都是false,但是整个flip-flop是true)
14, false...false, collect
15, false...true, collect (右侧是true了,整个flip-flop是false了)
16, true...false, collect (左侧又是true了)
17, false...false, collect
18, false...true, collect (右侧是true了,整个flip-flop是false了)
19, false...false, pass
20, true...false, collect

关键是知道整个 flip-flop 表达式有内部状态,还有何时根据左右表达式改变内部状态

貌似是这么解释的,实际上从来没用过这玩意儿。

#1 楼 @kgen 确实是晦涩难懂

首先要了解有 flip-flop 的返回值是根据下面一个图的最终状态决定的。unset 对应 false,set 对应 true。每次根据上次缓存的状态 (初始是 unset),然后考虑这一次的..(或者...) 的左右 bool 值进行状态调整。最终的状态对应的 bool 值就是返回值(并且写入缓存,以被下次使用) ..和...的主要区别是体现在上一次的状态是 unset, 要处理的表达式是 true..true 的时候,处理结果不一致 ..看到左边是 true,则从 unset 进入 set 状态,然后标记整个表达式返回值为 true,并根据右边表达式的值再次转换到 unset 状态,因此下一次处理的时候,缓存值就是 unset(false). 而...看到左边是 true,则从 unset 进入 set 状态,然后标记整个表达式返回值为 true,并忽略右边表达式的值。。

@luikore 说的很详细,只是输出 log 有下面几处错误 15, false..false, pass 17, true..false, collect 18, true..true, collect

Progmatic Programming Ruby page 138

需要 登录 后方可回复, 如果你还没有账号请 注册新账号