Rubocop抱怨: Style / GuardClause:使用保护子句而不是将代码包装在条件表达式中。 如果issue_flag == true&& issue_notification_sent&& !issue_notification_follow_up_sent&& send_follow_up ^^
我的原始代码是
if issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
并且从阅读docs开始,我似乎可以通过实现以下代码来解决这个问题:
return unless issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
我可以看到,除非符合条件,否则这基本上会从方法中提前破坏,但对我而言,这似乎不太可读。它似乎也不太可维护,因为在此代码之后无法添加其他条件,除非它们在第一行传递条件,例如,如果issue_flag == true && !issue_notification_sent
执行其他操作(任何符合此条件的条件已经在第1行返回)上面重构的代码。)
有没有更好的方法来重构这个,以便在下面的代码之后添加更多条件,而不会过早地返回代码?
感谢。
答案 0 :(得分:0)
我认为我们可以做类似下面的事情
# issue_flag is boolean so we can directly put it
# create a new method with all the condition and give a proper name
return unless issue_flag && send_follow_up? # change name accourdingly
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
# document its behaviour
def send_follow_up?
issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
end
保护结构用于将控件发送出阻止,因此如果您需要更改某些内容或在该条件之后执行某些操作,则您将无法使用保护条款。在这种情况下看看下面的代码,我们不会使用保护条款
def test
if something_here?
do_something
end
do_something_else
do_something_else1
do_something_else2
end
答案 1 :(得分:0)
我可能会将该方法的大部分内容提取为具有清晰名称的私有部分,以表明其意图。伪代码实现如下所示:
def method_name
return unless flag? && issue_notification_sent_with_follow_up
log_follow_up
UserMailer.issue_notification(self, @email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
private
def flag?
issue_flag == true
end
def issue_notification_sent_with_follow_up
issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
end
def log_follow_up
@email_address = "sales@test.com"
puts "Emailing Follow Up #{@email_address} - #{sales_order}"
end