干燥红宝石三元
Posted
技术标签:
【中文标题】干燥红宝石三元【英文标题】:DRY up Ruby ternary 【发布时间】:2011-06-05 13:49:23 【问题描述】:我经常遇到这样的情况,我想做一些条件逻辑,然后返回部分条件。如何在不重复真假表达式中的条件部分的情况下做到这一点?
例如:
ClassName.method.blank? ? false : ClassName.method
有什么办法可以避免重复ClassName.method
?
这是一个真实的例子:
PROFESSIONAL_ROLES.key(self.professional_role).nil? ?
948460516 : PROFESSIONAL_ROLES.key(self.professional_role)
【问题讨论】:
DRY 是在重复代码块、长链方法序列或只是做一些重复可能会降低代码质量的事情时非常有意义的事情之一.我认为当你做一些简单的事情并且不得不跳过一个箍来成为 DRY-er 时,这是没有意义的。我们很容易被引诱去追逐 DRY 龙,而忘记了“足够好”。在您的示例中,如果您要循环数百万次,则添加一个临时变量或执行@sepp2k 所说的||
事情,否则不要太担心。
【参考方案1】:
假设您可以接受 false
与 nil
相同的处理方式,则使用 ||
:
PROFESSIONAL_ROLES.key(self.professional_role) || 948460516
如果key
返回nil
或false
,这将返回948460516
,否则返回对key
的调用的返回值。
请注意,如果key
返回nil
或false
,则只会返回 948460516,而不是返回空数组或字符串。由于您在第二个示例中使用了nil?
,我认为这没关系。但是您在第一个示例中使用了blank?
(并且blank?
为空数组和字符串返回true
),所以我不确定。
【讨论】:
【参考方案2】:如果你只是想 DRY,那么你可以使用一个临时变量:
x = ClassName.method
x.blank? ? false : x
x = PROFESSIONAL_ROLES.key(self.professional_role)
x.nil? ? 948460516 : x
如果不想使用临时变量,可以使用块:
Proc.new do |x| x.blank? ? false : x end.call(ClassName.method)
Proc.new do |x| x.nil? ? 948460516 : x end.call(PROFESSIONAL_ROLES.key(self.professional_role))
对于您描述的情况(您只想在默认检查失败时使用原始值),编写一个辅助方法很简单:
def x_or_default(x, defval, checker = :nil?)
if x.send(checker) then defval else x end
end
x_or_default(ClassName.method, false, :blank?)
x_or_default(PROFESSIONAL_ROLES.key(self.professional_role), 94840516)
这与所描述的||
方法非常相似,但也适用于您的blank?
示例。
我通常在这类事情上使用临时变量。
【讨论】:
【参考方案3】:我知道这看起来不太漂亮,但它确实让事情变得有点干燥。
a = "ABC"
b = (temp = a.downcase).length < 3 ? "---" : temp
如果您出于某种原因不想创建 temp
变量,您可以重用已经存在的东西,例如 $_
。
【讨论】:
以上是关于干燥红宝石三元的主要内容,如果未能解决你的问题,请参考以下文章