重构嵌套的if语句:首先检查块是否存在,然后在block.call上应用另一个if语句

时间:2013-07-21 02:13:41

标签: ruby if-statement refactoring nested

我有以下接受可选块的方法,我用以下方式编写它:

def top_method(&block)
  if block
    if block.call == 1
      another_method_1
      another_method_2
    end
  else
    another_method_3
  end
end

起初我认为可以按如下方式进行重构:

if block.call == 1
  another_method_1
  another_method_2
else
  another_method_3
end

但是如果没有阻止传递给block.call,我在callnil上调用top_method)时收到错误。有没有办法在第一个if语句中只用一个条件重写上面的方法(比如在出现错误时跳过它)?

另外,我想知道我是否可以将内部if语句重构为一行。有没有办法做到这一点?我的意思如下:

if block
  (run another_method_1 and another_method_2) if block.call == 1
end

提前致谢! :)

4 个答案:

答案 0 :(得分:4)

我可以提供技巧,但我认为这段代码真正需要的是一些面向对象的编程。但是,如果不知道你正在做什么的语义,很难想出一个改进的设计。所以,这是一个技巧。

您可以考虑为该块提供默认值。正如评论中所指出的,目前你想要做的事情有些含糊不清。在这里,我假设您的第二个片段的语义:

def top_method(&block)
  block ||= lambda {}
  if block.call == 1
    another_method_1
    another_method_2
  else
    another_method_3
  end
end

如果未传入任何块,则将块设置为lambda {}。在这种情况下,Lambda就像一个块:它响应调用,并具有返回值。在这种情况下,拥有一个空体,它返回 nil 。由于 nil 不等于1, if else 部分将被执行。

答案 1 :(得分:1)

我会将2个内在条件写入1个陈述中。

def top_method(&block)
  if block && block.call
    another_method1
    another_method2
  else
    another_method3
  end
end

答案 2 :(得分:1)

def top_method(&block)
  if block_given? && block.call == 1
    1
    2
  else
    3
  end
end

puts top_method
puts top_method {1}

答案 3 :(得分:1)

def top_method(&block)
  if block and block.call == 1
    method1
    method2
  else
    method3
  end
end

...

  

另外,我想知道我是否可以重构内部if语句   分成一行。有没有办法做到这一点?我的意思如下:

    if block
      (run another_method_1 and another_method_2) if block.call == 1
    end

Thanks in advance! :)

当然 - 如果你想加入那些写不好的红宝石的人。然后你仍然需要写一个if语句来处理你的else子句。一个衬里永远不应该是你的目标。代码清晰度更重要。

lambda {meth1;meth2}.call if block and block.call == 1