内联哈希分配和使用

时间:2018-03-20 06:50:19

标签: ruby

我有以下方法声明:

  def do_staff
    param_a = condition1 && condition2
    param_b = 100
    param_c = param_a ? 'good' : 'bad'
    # method logic implementation ....
  end

使用rubocop gem分析我的代码后,我发现do_staff有超过10行代码,因此我需要将params定义添加到单个哈希中,例如:

args = { param_a: condition1 && condition2, param_b: 100, param_c: args[:param_a] ? 'good' : 'bad' }

由于argsundefined method '[]' for nil:NilClass声明肯定会抛出param_c

{ param_c: args[:param_a] ? 'good' : 'bad' }

问题是:

在Ruby中是否有可能实现这样的内联声明,我可以避免在定义param_a时重复param_c定义的逻辑?

1 个答案:

答案 0 :(得分:1)

如果你有这样的一行

variable = { a: 1, b: variable[:a] }

然后首先评估赋值的右侧 - 这意味着首先定义散列。然后在第二步中,将定义的散列分配给左侧的变量。因此,哈希定义中的variable[:a]引用必须失败,因为哈希尚未在该时间点分配给variable

在你的例子中,我会将params_a的条件单独提取到一个方法中 - 如果评估费用很高 - 记住它的结果:

def do_staff
  {
    param_a: a_condition,
    param_b: 100,
    param_c: (a_condition ? 'good' : 'bad')
  }
end

private

def a_condition
  # note we cannot use `||=` here because the result 
  # of the condition might be `nil` or `false`
  @a_condition = condition1 && condition2 unless defined?(@a_condition)
end

或者您可以在do_staff方法中进行一次评估:

def do_staff
  a_condition = condition1 && condition2

  {
    param_a: a_condition,
    param_b: 100,
    param_c: (a_condition ? 'good' : 'bad')
  }
end

此外,我建议将a_condition ? 'good' : 'bad'部分单独移动到一个方法中 - 只是为了提高可读性。但是,重构取决于您的依赖关系,并且可能在您的问题中的示例代码的上下文中没有多大意义。