接下来与if。在一个.each循环中?

我有一个文本处理的东西,我在Ruby中做。 基本上,我必须实现一个简单的状态机(一个字符后视)。

我的代码目前看起来像这样:

text.each{ |c| ... ... ... ... if @state!=:some_state next end #processing stuff for if in :some_state mode ... ... ... ... ... } 

这是对的吗? 或者它应该像下面这样实现:

 text.each{ |c| ... ... ... ... if @state==:some_state #processing stuff for if in :some_state mode ... ... ... ... ... end } 

有正确的方式还是只是偏好? 哪一个与做事的“ruby方式”更加融合?

与@DigitalRoss完全一致,如果在评估某些条件后存在复杂的代码,我看到有人使用next

  next if @state!=:some_state # some long complicated code 

另一方面,如果有一个简单的操作需要在某些条件的基础上进行,那么我更愿意

  if @state == :some_state #call_a_method_to_do_something end OR call_a_method if @state == :some_state 

话虽如此,编写冗长的复杂代码却是不好的做法。 如果您的代码干净且设计良好,那么您将永远不必在代码中使用next

我认为你给出的例子并没有真正捕捉到next做出改变的情况。 考虑一下代码中有多个“next-points”的情况:

 text.each do |c| next if @state == :state1 ... next if @state == :state2 ... next if @state == :state3 ... end 

并将其与if-variant进行比较:

 text.each do |c| unless @state == :state1 ... unless @state == :state2 ... unless @state == :state3 ... end end end end 

虽然第一种可以被一些纯粹主义者视为意大利面风格,但恕我直言,它比后者更具可读性。

这是第二种方式

一些思想流派反对各种语言的东西,如下nextretrycontinuebreak ,因为他们只是在不受尊重的goto声明的方向上有点过分。

这些语句确实有它们的用例,但总的来说,当一个结构化的向下指向的结构将完成相同的事情时,故意“spaghettify”代码是一个坏主意。 现在,如果条件要求跳过整个循环体,那么我可能更喜欢使用next

我会去:

 text.each{ |c| ... ... Generic state processing ... case @state when :state_1 then code when :state_2 then code end } 

但如果它与第一个样本一样(意味着只有1个状态需要额外的处理)

 text.each{ |c| ... ... Generic state processing ... next unless @state == :state_1 ... ... Code that process states other than :state_1 } 

更进一步而不是点击实例变量,如果对象是否处于我们需要的状态,它听起来更好听:

 def processed? @state == :state_1 end ... next unless processed? # sounds like natural language... ... 

进一步推理,我认为一个内衬就像’下一个除非处理?’ 只有当同一个缩进级别的代码不超过10行时才是好的,否则我宁愿做另一个,所以缩进将帮助我乍看之下发生了什么