Ruby Flip Flop Operator in Ruby [Ruby 中的触发器操作] (..)

palytoxin · November 24, 2014 · Last by palytoxin replied at November 25, 2014 · 2162 hits

翻译自Flip Flop Operator in Ruby reddit 上看到的,因为从来没看到过这种用法,一起学起~ E 文不好请多指教

触发器操作符是一种很奇怪的 ruby 特性,大多数人甚至都没有意识到它的存在。这种特性是从 perl 风格中继承而来,但是几乎没有人使用。在这片文章中,我们将会看到什么是触发器操作符 [flip-flop operators],并且学习他是如何使用的。

什么是触发器操作符 [flip-flop operators]?

触发器操作符 和 range 操作符 (..) 一样,条件声明在操作符两边。类似下面这样:

(1..20).each do |x|
  puts x if x == 5 .. x == 10
end
#=>
5
6
7
8
9
10
  1. 直到第一个表达式为 true 之前 整个表达式的结果为 false。
  2. 以上条件成立后,在第二个表达式为 true 之前,表达式结果是 true。

在上面那个例子中 x==5 之后 x==10 之前等式成立,所以输出了 5 到 10 这几个数字。

其他的例子

让我们再举一个例子,看看操作符的更多行为。想象一下,当你解析一个有缩进标记和反缩进标记的文件时。每当碰到一个缩进符号就打开缩进,当碰到一个反缩进符号时就将缩进关掉。

这个例子中,我们尝试处理一下文本:

zero indentation
indent
inside block
dedent
after the block
indent
another block
dedent
end of file

当输出之后,它看起来应该是这样的:

zero indentation
  indent
  inside block
  dedent
after the block
  indent
  another block
  dedent
end of file

在这个例子中,我们需要跟踪缩进的状态。触发器操作符的处理会让我们眼前一亮。

lines = File.readlines('somefile')

lines.each do |line|
  if line =~ /^indent/ .. line =~ /^dedent/
    puts " " + line
  else
    puts line
  end
end

现在这个操作符看起来有点用了。你可以这么理解:从包含"indent"的地方开始,到遇到"dedent"的地方,在每一行的开始都加上两个空格。

这种特性将会从 ruby 中移除么?

移除这个特性的 issue 已经被提出来了。在 ruby2.0 发布之前,Matz 说如果要删除这个特性,那也应该等到 ruby3.0。

Under the current plan, I am not going to remove flip-flop from 2.0, since we are not going to made incompatible changes anytime soon. We have to wait until 3.0. (–Matz)

我并不是这种语法的强烈依赖者,并且几乎不会在我的代码中用到。如果这种特性在将来被移除,并不会引起太多的错误。

在过去几年在这个问题上并没有过多的活动,所以也不能确定在某一天这个特性会被移除。但是通过了解这种语法,我们能够在见到这种代码的时候不至于莫名奇妙。

外部链接

Feature #5400 - Remove flip-flops in 2.0 - the discussion on the Ruby issue tracker

在我的 rmbp 上,帖子右下角的按钮对齐很奇怪,是我个人的问题么?

@palytoxin Ubuntu14.04 chrome Version 38.0.2125.122 (64-bit) 正常

@palytoxin loop 表示的是一个集合区间,

(1..20.1).include?(2)  会成立,很典型的区间

loop 看成是区间就好了,不要在给他其他东西!

#3 楼 @colorfulberry flip-flop 和 range 完全不是一个东西。

5 Floor has deleted
You need to Sign in before reply, if you don't have an account, please Sign up first.