有没有更好的方法来分配 Ruby 哈希同时避免 RuboCop 的 ABC 大小警告?
Is there a better way to assign a Ruby hash while avoiding RuboCop's ABC Size warnings?
我有一个构建笔记本电脑属性的方法,但前提是属性出现在给该方法的行中:
def build_laptop_attributes desk_id, row, laptop
attributes = {}
attributes[:desk_number] = room_id if laptop && desk_id
attributes[:status] = row[:state].downcase if row[:state]
attributes[:ip_address] = row[:ip_address] if row[:ip_address]
attributes[:model] = row[:model] if row[:model]
attributes
end
目前,RuboCop 说 Metric/AbcSize 太高了,我想知道是否有一种明显且干净的方法来分配这些属性?
减少条件数量的替代版本(假设您正在检查 nil / 初始化值):
def build_laptop_attributes desk_id, row, laptop
attributes = {}
attributes[:desk_number] = room_id if laptop && desk_id
attributes[:status] = row[:state]&.downcase
attributes[:ip_address] = row[:ip_address]
attributes[:model] = row[:model]
attributes.compact
end
移除作业检查需要额外 .compact
成本。
风格指南提供“最佳实践”;在需要时评估和调整
首先,RuboCop 是咨询。仅仅因为 RuboCop 抱怨某事并不意味着它在某种绝对意义上是错误的;这只是意味着你应该多消耗一点头骨汗水(正如你所做的那样),看看你所做的是否有意义。
其次,您没有提供 self-contained 可执行示例。这使得 SO 读者无法可靠地重构它,因为如果没有原始 post 中未提供的样本输入和预期输出,目前无法对其进行测试。您自己也需要这些东西来评估和重构您自己的代码。
最后,ABC Metric 查看赋值、分支和条件。你有五个赋值,四个条件,看起来像是一个方法调用。很多吗?如果您还没有调整过 Rubocop,答案是“RuboCop 这么认为”。您是否同意取决于您和您的团队。
如果您想尝试喂养 Rubocop,您可以做一些可能有助于降低指标的事情:
- 重构作业的数量和复杂性。一些可能的例子包括:
用安全导航器 (&.
) 替换您的 postfix if-statements 以防止在 nil
.
上调用方法
将您的一些分支逻辑和条件提取到“做正确的事情”的方法,可能会将您当前的方法减少为具有四个方法调用的单个赋值。例如:
attributes = { desk_number: location, status: laptop_status, ... }
用解构任务替换所有的多重任务(尽管 Rubocop 也经常抱怨这些)。
- 首先重新审视您是否拥有正确的数据结构。也许您真的只想要一个 OpenStruct 或其他一些数据对象。
您当前的代码看起来可读性很强,那么榨汁真的值得吗?如果您确定 RuboCop 在这种特殊情况下被误导,并且您的代码可以正常工作并通过内部代码审查,那么您可以在项目的 .rubocop.yml or disable that particular metric 中针对源代码的那部分调整指标的敏感度。
阅读@Todd A. Jacobs 的回答后,您可能想要(或不想)这样写:
def build_laptop_attributes desk_id, row, laptop
desk_number = room_id if laptop && desk_id
{
desk_number: desk_number,
status: row[:state]&.downcase,
ip_address: = row[:ip_address],
model: row[:model]
}.compact
end
这 reduce 的优点是减少了对 []=
的调用次数,以及在单个 compact
.
中分解许多 if
s
在我看来,它更具可读性,因为它更简洁,因为重点完全在于你的键和值之间的对应关系。
我有一个构建笔记本电脑属性的方法,但前提是属性出现在给该方法的行中:
def build_laptop_attributes desk_id, row, laptop
attributes = {}
attributes[:desk_number] = room_id if laptop && desk_id
attributes[:status] = row[:state].downcase if row[:state]
attributes[:ip_address] = row[:ip_address] if row[:ip_address]
attributes[:model] = row[:model] if row[:model]
attributes
end
目前,RuboCop 说 Metric/AbcSize 太高了,我想知道是否有一种明显且干净的方法来分配这些属性?
减少条件数量的替代版本(假设您正在检查 nil / 初始化值):
def build_laptop_attributes desk_id, row, laptop
attributes = {}
attributes[:desk_number] = room_id if laptop && desk_id
attributes[:status] = row[:state]&.downcase
attributes[:ip_address] = row[:ip_address]
attributes[:model] = row[:model]
attributes.compact
end
移除作业检查需要额外 .compact
成本。
风格指南提供“最佳实践”;在需要时评估和调整
首先,RuboCop 是咨询。仅仅因为 RuboCop 抱怨某事并不意味着它在某种绝对意义上是错误的;这只是意味着你应该多消耗一点头骨汗水(正如你所做的那样),看看你所做的是否有意义。
其次,您没有提供 self-contained 可执行示例。这使得 SO 读者无法可靠地重构它,因为如果没有原始 post 中未提供的样本输入和预期输出,目前无法对其进行测试。您自己也需要这些东西来评估和重构您自己的代码。
最后,ABC Metric 查看赋值、分支和条件。你有五个赋值,四个条件,看起来像是一个方法调用。很多吗?如果您还没有调整过 Rubocop,答案是“RuboCop 这么认为”。您是否同意取决于您和您的团队。
如果您想尝试喂养 Rubocop,您可以做一些可能有助于降低指标的事情:
- 重构作业的数量和复杂性。一些可能的例子包括:
用安全导航器 (
上调用方法&.
) 替换您的 postfix if-statements 以防止在nil
.将您的一些分支逻辑和条件提取到“做正确的事情”的方法,可能会将您当前的方法减少为具有四个方法调用的单个赋值。例如:
attributes = { desk_number: location, status: laptop_status, ... }
用解构任务替换所有的多重任务(尽管 Rubocop 也经常抱怨这些)。
- 首先重新审视您是否拥有正确的数据结构。也许您真的只想要一个 OpenStruct 或其他一些数据对象。
您当前的代码看起来可读性很强,那么榨汁真的值得吗?如果您确定 RuboCop 在这种特殊情况下被误导,并且您的代码可以正常工作并通过内部代码审查,那么您可以在项目的 .rubocop.yml or disable that particular metric 中针对源代码的那部分调整指标的敏感度。
阅读@Todd A. Jacobs 的回答后,您可能想要(或不想)这样写:
def build_laptop_attributes desk_id, row, laptop
desk_number = room_id if laptop && desk_id
{
desk_number: desk_number,
status: row[:state]&.downcase,
ip_address: = row[:ip_address],
model: row[:model]
}.compact
end
这 reduce 的优点是减少了对 []=
的调用次数,以及在单个 compact
.
if
s
在我看来,它更具可读性,因为它更简洁,因为重点完全在于你的键和值之间的对应关系。