【问题标题】:Better way to write methods that return methods based on a set of conditions in Ruby编写基于 Ruby 中的一组条件返回方法的方法的更好方法
【发布时间】:2017-07-20 16:26:21
【问题描述】:

我遇到了一个问题,循环复杂度对于这个 ruby​​ 方法来说太高了:

def find_value(a, b, lookup_value)
  return find_x1(a, b) if lookup_value == 'x1'
  return find_x2(a, b) if lookup_value == 'x2'
  return find_x3(a, b) if lookup_value == 'x3'
  return find_x4(a, b) if lookup_value == 'x4'
  return find_x5(a, b) if lookup_value == 'x5'
  return find_x6(lookup_value) if lookup_value.include? 'test'
end

有没有不用eval的写法?

【问题讨论】:

    标签: ruby cyclomatic-complexity


    【解决方案1】:

    试试这个:

    def find_value(a, b, lookup_value)
      return find_x6(lookup_value) if lookup_value.include? 'test'
      send(:"find_#{lookup_value}", a, b)
    end
    

    send() 允许您使用字符串或符号按名称调用方法。第一个参数是方法的名称;以下参数只是传递给被调用的方法。

    【讨论】:

    • 可能 #public_send 取决于实现,特别是如果还有 find_XXX 私有方法
    【解决方案2】:

    如果您需要一些灵活性,查找方法或类名并没有错:

    LOOKUP_BY_A_B = {
      'x1' => :find_x1,
      'x2' => :find_x2,
      'x3' => :find_x3,
      'x4' => :find_x4,
      'x5' => :find_x5,
    }.freeze
    
    def find_value(a, b, lookup_value)
      method = LOOKUP_BY_A_B[lookup_value]
      return self.send(method, a, b) if method
      find_x6(lookup_value) if lookup_value.include? 'test'
    end
    

    您还可以查找 Procs,例如

    MY_PROCS = {
      1 => proc { |a:, b:| "#{a}.#{b}" },
      2 => proc { |a:, b:| "#{a}..#{b}" },
      3 => proc { |a:, b:| "#{a}...#{b}" }
    }.freeze
    
    def thing(a, b, x)
      MY_PROCS[x].call(a: a, b: b)
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多