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

Ruby 重构嵌套的if语句:首先检查块是否存在,然后在block.call上应用另一条if语句,ruby,if-statement,refactoring,nested,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_meth

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

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
if block
  (run another_method_1 and another_method_2) if block.call == 1
end
    if block
      (run another_method_1 and another_method_2) if block.call == 1
    end

Thanks in advance! :)
但是我在block.call上得到了一个错误,如果没有块被传递给top_方法,那么调用在nil上被调用。有没有一种方法可以在第一个if语句中只使用一个条件重写上面的方法,比如在出现错误时跳过它

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

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

Thanks in advance! :)

提前谢谢!:

我会把这两个内部条件写进一个语句中

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

我可以提供一些技巧,但我认为这段代码真正需要的是一些面向对象的编程。然而,如果不了解您正在做的事情的语义,就很难提出改进的设计。所以,一个小把戏

你可以考虑给块一个默认值。正如评论中提到的,目前你想做的事情有些模棱两可。这里我假设您的第二个代码段的语义:

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部分

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

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

if block.call == 1
  another_method_1
  another_method_2
else
  another_method_3
end
if block
  (run another_method_1 and another_method_2) if block.call == 1
end
    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

如果block不存在,那么对block的调用也会出错。你想使用block_吗?要进行检查,@vgoff,if块执行与给定的检查块\u相同的操作:由于该块被设置为显式参数,因此如果该块不存在,它将被指定为nil。谢谢。我忽略了这一细微差别。条件block.call不是很有用,当然也不能满足op的要求。您可能的意思是如果block&&block.call==1。您的第一个代码段和第二个代码段除了您得到的错误之外还有一个根本性的区别:如果代码段存在,但返回的不是1,那么上面的代码段将不起任何作用。第二个代码段,如果该块存在并且返回的不是1,则调用另一个\u方法\u 3。你的目的是哪一个?你不需要lambda中的0。你可以说&block=lambda{},或者在1.9+中&block=->{}@WayneConrad,谢谢你的技巧。我试图运行此程序,但现在出现语法错误:SyntaxError:irb:1:语法错误,意外“=”,应为def top_method&block=lambda{}^irb:1:语法错误,意外,应为$end@adler我真丢脸。我已经修复了语法错误,谢谢你。+++使用block_given?,但是-没有执行op想要的操作,即检查块的返回值以确定下一个操作过程。屈服于事无补,你说得太对了。我们将在那里使用逻辑运算符。这意味着我不能使用收益率。我把注意力集中在这个事实上,收益率从这个方法中返回。谢谢。不过我更喜欢Wayne的答案,因为它默认提供了一个作为lambda的Proc。我认为检查变量的内容比调用一个不做任何事情的方法更有效,而且默认情况下是非常混乱的。同意性能,但如果需要发生性能问题,将其延迟到调用该方法为止?如果询问是否给出了块,为什么需要一个默认进程,我同意。但好处是他的代码并不要求,它告诉我们。