我有一个臭的方法,如:
def search_record(*args) record = expensive_operation_1(foo) return record unless record.nil? record = expensive_operation_2(foo,bar) return record unless record.nil? record = expensive_operation_3(baz) return record unless record.nil? record = expensive_operation_4(foo,baz) return record unless record.nil? end
有没有一个很好的ruby成语“回调结果除非”?
还是应该写一个return_unless_nil(& blk)方法?
(注意,每个调用的参数都不同,所以我不能简单地迭代它们)
解决方法
你关心这里的零和差的区别吗?如果你只关心每个方法的返回值是否为“falsy”,那么这是一个非常Rubyy的方法:
def search_record(*args) expensive_operation_1(foo) || expensive_operation_2(foo,bar) || expensive_operation_3(baz) || expensive_operation_4(foo,baz) end
如果你不熟悉这个成语,那么可以解释一下:Ruby,像大多数语言一样,“short circuits”或者比较,这意味着如果第一个操作数评估为“truey”,那么它不会打扰评估第二个操作数(即如果expensive_operation_1返回不是nil或false的东西,它不会调用expensive_operation_2),因为它已经知道布尔运算的结果为true.
Ruby所做的另一个有用的事情是,而不是从布尔运算返回true或false,它只返回它所评估的最后一个操作数.所以在这种情况下,如果expensive_operation_1返回nil,那么它将调用expensive_operation_2,如果返回一个值(这不是错误的),那么整个表达式只会计算该值.
最后,我们可以链接这些布尔,所以实际上将返回第一个不是假的操作数的结果,从不评估后续的操作数.如果所有的操作数评估为伪造,它将返回最终的操作数(我们知道这是错误的,在你的情况下可能为零).