ruby - 重构 if else 语句
ruby - refactoring if else statement
我已经尝试阅读一些关于重构的教程,但我正在为条件判断而苦苦挣扎。我不想使用三元运算符,但也许这应该在方法中提取?或者有使用地图的聪明方法吗?
detail.stated = if value[:stated].blank?
nil
elsif value[:stated] == "Incomplete"
nil
elsif value[:is_ratio] == "true"
value[:stated] == "true"
else
apply_currency_increment_for_save(value[:stated])
end
stated = value[:stated]
detail.stated = case
when stated.blank? || stated == "Incomplete"
nil
when value[:is_ratio] == "true"
value[:stated] == "true"
else
apply_currency_increment_for_save stated
end
发生了什么: 当 case
不带表达式使用时,它变成了 if ... elsif ... else ... fi.
的文明等价物
你也可以使用它的结果,就像 if...end
.
将代码移至apply_currency_increment_for_save
并做:
def apply_currency_increment_for_save(value)
return if value.nil? || value == "Incomplete"
return "true" if value == "true"
# rest of the code. Or move into another function if its too complex
end
逻辑被封装,只需要2行
如果您将此逻辑移动到一个方法中,由于早期 return
(和关键字参数),它可以变得更清晰:
def stated?(stated:, is_ratio: nil, **)
return if stated.blank? || stated == "Incomplete"
return stated == "true" if is_ratio == "true"
apply_currency_increment_for_save(stated)
end
然后...
detail.stated = stated?(value)
我喜欢@Jordan 的建议。但是,调用似乎不完整——'is_ratio' 参数也是从值中选择的,但未提供。
为了争论,我建议你可以更进一步,提供一个 class,它非常专注于评估 "stated" 值。这可能看起来很极端,但它符合单一责任的概念(责任是评估 "value" 的陈述——而 'detail' 对象可能专注于其他事情并且仅仅利用评估)。
看起来像这样:
class StatedEvaluator
attr_reader :value, :is_ratio
def initialize(value = {})
@value = ActiveSupport::StringInquirer.new(value.fetch(:stated, ''))
@is_ratio = ActiveSupport::StringInquirer.new(value.fetch(:is_ratio, ''))
end
def stated
return nil if value.blank? || value.Incomplete?
return value.true? if is_ratio.true?
apply_currency_increment_for_save(value)
end
end
detail.stated = StatedEvaluator.new(value).stated
请注意,这利用了 Rails' StringInquirer class.
我已经尝试阅读一些关于重构的教程,但我正在为条件判断而苦苦挣扎。我不想使用三元运算符,但也许这应该在方法中提取?或者有使用地图的聪明方法吗?
detail.stated = if value[:stated].blank?
nil
elsif value[:stated] == "Incomplete"
nil
elsif value[:is_ratio] == "true"
value[:stated] == "true"
else
apply_currency_increment_for_save(value[:stated])
end
stated = value[:stated]
detail.stated = case
when stated.blank? || stated == "Incomplete"
nil
when value[:is_ratio] == "true"
value[:stated] == "true"
else
apply_currency_increment_for_save stated
end
发生了什么: 当 case
不带表达式使用时,它变成了 if ... elsif ... else ... fi.
你也可以使用它的结果,就像 if...end
.
将代码移至apply_currency_increment_for_save
并做:
def apply_currency_increment_for_save(value)
return if value.nil? || value == "Incomplete"
return "true" if value == "true"
# rest of the code. Or move into another function if its too complex
end
逻辑被封装,只需要2行
如果您将此逻辑移动到一个方法中,由于早期 return
(和关键字参数),它可以变得更清晰:
def stated?(stated:, is_ratio: nil, **)
return if stated.blank? || stated == "Incomplete"
return stated == "true" if is_ratio == "true"
apply_currency_increment_for_save(stated)
end
然后...
detail.stated = stated?(value)
我喜欢@Jordan 的建议。但是,调用似乎不完整——'is_ratio' 参数也是从值中选择的,但未提供。
为了争论,我建议你可以更进一步,提供一个 class,它非常专注于评估 "stated" 值。这可能看起来很极端,但它符合单一责任的概念(责任是评估 "value" 的陈述——而 'detail' 对象可能专注于其他事情并且仅仅利用评估)。
看起来像这样:
class StatedEvaluator
attr_reader :value, :is_ratio
def initialize(value = {})
@value = ActiveSupport::StringInquirer.new(value.fetch(:stated, ''))
@is_ratio = ActiveSupport::StringInquirer.new(value.fetch(:is_ratio, ''))
end
def stated
return nil if value.blank? || value.Incomplete?
return value.true? if is_ratio.true?
apply_currency_increment_for_save(value)
end
end
detail.stated = StatedEvaluator.new(value).stated
请注意,这利用了 Rails' StringInquirer class.