2015-10-27 25 views
4

我编码在Ruby的一些地方,从一个方法调用给定的值foo输出干净的方法,我想:红宝石 - 如果truthy返回一个值,或执行任意代码

  • 返回foo如果foo is truthy
  • 如果foo是伪造的,则记录错误并返回默认值。

实现这个最简单幼稚的方法可能是:

foo = procedure(input) 

if foo 
    foo 
else 
    log_error 
    default 
end 

但由于foo重复三次这种感觉过于冗长,而这种风格是非常必要的。

写这个最干净,最习惯的方法是什么?

(性能matters--我们假设foo在绝大多数情况下truthy。)

回答

5

靠着Ruby的Perl传统:

foo = procedure(input) and return foo 
log_error 
default 
2

你可以写,如果log_error返回真值

foo || log_error && default 

如果不是:

foo || (log_error; default) 
+2

'FOO ||的log_error;默认' - 将评估'foo || log_error;'作为一个语句,'default'作为另一个语句 - 这可能不是你的意图。 –

+0

我没有意识到你可以将Ruby语句组合在一起(带圆括号),但它是完全合理的。 POLA再次夺冠!我想知道它与'begin'..''end'块有什么不同? – mwp

3

这是一个罕见的情况下Ruby的匿名块实际上是有用的:

foo = procedure(input) || begin 
    log_error 
    default 
end 
+0

是的!为了整个社区的缘故,我可以用最多的选票接受答案是最有意义的,但这正是我个人所期待的。我只是测试了一下,看起来你可以在没有赋值的情况下编写它。我不知道你可以在Ruby中做到这一点。出于好奇,是否可以用'{...}'而不是'begin ... end'来编写匿名块? –

+0

不,但您可以使用parens per @ Arsen的答案。 :-) – mwp

0

为了完整起见(且因为没有人贴吧还)我会在一个答案加我原来的尝试:

procedure(input) || proc { 
    log_error 
    default 
}.call 

我想不出任何理由超过@ MWP的答案用这个:

procedure(input) || begin 
    log_error 
    default 
end 

因为抽的涉及创建Proc对象的开销(性能和可读性)。虽然一些快速基准测试显示,在大多数情况下性能差异应该可以忽略不计,因为除非procedure(input)是虚假的,否则Proc对象似乎不会创建。

0

所有的事情考虑,我会去:

foo = procedure(input) 
return foo if foo 
log_error 
default