我有以下接受可选块的方法,我用以下方式编写它:
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
(nil
上调用top_method
)时收到错误。有没有办法在第一个if
语句中只用一个条件重写上面的方法(比如在出现错误时跳过它)?
另外,我想知道我是否可以将内部if
语句重构为一行。有没有办法做到这一点?我的意思如下:
if block
(run another_method_1 and another_method_2) if block.call == 1
end
提前致谢! :)
答案 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