所以我试着走正确的路,理解如何解决这个问题,这看起来像一小段代码,为什么它会抱怨?
移动嵌套的if-else不会改变任何东西,对如何解决这个cop有什么建议吗?
class WebPush::Register
include Interactor
# rubocop:disable Metrics/AbcSize
def call
user = Learner.find_by(id: context.user_id)
# return if existing
if user.web_push_subscription
context.subscription = user.web_push_subscription
else
subscription = WebPushSubscription.new(
endpoint: context.push_params[:endpoint],
auth_key: context.push_params[:keys][:auth],
p256dh_key: context.push_params[:keys][:p256dh],
learner: user
)
if subscription.save
context.subscription = subscription
else
context.error = subscription.errors.full_messages
context.fail!
end
end
end
# rubocop:enable Metrics/AbcSize
end
2条答案
按热度按时间qltillow1#
首先,你需要了解ABC是如何计算的。嵌套条件不会影响ABC。RuboCop的警告输出会显示计算结果:
<5, 28, 4>
就是您的<Assignments, Branches, Conditionals>
,如this article中所述。总分计算如下:
sqrt(5^2 + 28^2 + 4^2) = 28.72
警察的默认最高分是17分。
我在下面的代码中标注了每一行的ABC值,请注意,每次引用
context
时,都会添加一个B点,这是因为context
不是call
的局部变量,所以ABC指标假设每次都是方法调用。如果设置了cop选项:CountRepeatedAttributes: false(这是我推荐的),它会把你的分数降到
19.1
。作为替代,您可以通过将
WebPushSubscription
的创建提取到它自己的方法中来降低分数,如下所示:这将在两种方法之间分配分数。注意
create_subscription
中的一些额外的ABC节省策略,如将push_params
赋值给变量,以及将dig
用于嵌套的哈希访问器。create_subscription
的最终分数介于12和16之间,具体取决于您使用的cop选项,call
介于6和8之间。一般来说,降低ABC分数所需要做的就是重构为更小的方法。
a0x5cqrl2#
ABC代表Assignment, Branch, Condition.
ABC = sqrt(A^2 + B^2 + C^2)
我们数一数。
这样得到18.2。默认情况下,17是Rubcop认为满意的最大值。
我们可以用几个简单的提取方法来处理这个问题。
经过这种重构,代码变得更简单,每个方法只做一件事,这就是ABC度量所鼓励的。