0

我有以下接受可选块的方法,并且我已经按照以下方式编写了它:

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传递call到. 有没有办法在第一条语句中只用一个条件重写上面的方法(比如在出错时跳过它)?niltop_methodif

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

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

提前致谢!:)

4

4 回答 4

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 的行为就像一个块:它响应call并有一个返回值。在这种情况下,有一个空的主体,它返回nil。由于nil不等于 1,因此将执行if的else部分。

于 2013-07-21T02:59:01.587 回答
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! :)

当然——如果你想加入那些编写糟糕的 ruby​​ 的人的行列。然后你仍然需要编写一个 if 语句来处理你的 else 子句。一个班轮永远不应该是你的目标。代码清晰更为重要。

lambda {meth1;meth2}.call if block and block.call == 1
于 2013-07-21T05:26:10.060 回答
1

我会将 2 个内部条件写入 1 个语句。

def top_method(&block)
  if block && block.call
    another_method1
    another_method2
  else
    another_method3
  end
end
于 2013-07-21T02:25:12.240 回答
1
def top_method(&block)
  if block_given? && block.call == 1
    1
    2
  else
    3
  end
end

puts top_method
puts top_method {1}
于 2013-07-21T02:53:42.817 回答