【问题标题】:Assignment Branch Condition too high分配分支条件太高
【发布时间】:2016-01-14 14:05:10
【问题描述】:

我有一个简单的类,它在初始化时接受一到八个参数。它将访问器设置为这些以供以后使用。 Rubocop 正试图以 ABC 太高为由逮捕我,但我不确定我所做的是否真的有什么问题。这是我在初始化时禁用检查的情况吗?

class Foo
  attr_accessor :one, :two, :three, :four
  attr_accessor :five, :six, :seven, :eight

  def initialize(p={})
    @one = p[:one] if p[:one].present?
    # ...
    @eight = p[:eight] if p[:eight].present?
  end
end

我对减小大小的唯一想法是在初始化时遍历我的所有 attr_accessors,查看在 has 中是否有相应的符号通过,如果有,则分配它。

class Foo
  attr_accessor :one, :two, :three, :four
  attr_accessor :five, :six, :seven, :eight

  def initialize(p={})
    instance_variables.each do |variable|
      send("@#{variable}") = p["#{send(variable)}".to_sym] if p["#{send(variable)}".to_sym].present?
    end
  end
end

但这似乎有点弱。

【问题讨论】:

    标签: ruby coding-style rubocop


    【解决方案1】:

    这是实现您想要做的事情的方法之一:

    class Foo
      attr_accessor(*%i[one two three four five six seven eight])
    
      def initialize(p = {})
        p.keys.each { |k| instance_variable_set("@#{k}", p.fetch(k, nil)) }
      end
    end
    

    查看Hash#fetch 方法。

    您也可以使用它来访问 p 变量的键值对,如果您决定使用一个变量而不是 8 个变量 (@p)


    编辑

    只是出于好奇写了这个版本(使用了一些元编程)——它会为添加的实例变量动态添加attr_accessor

    class Foo
      def initialize(p = {})
        p.keys.each do |k|
          instance_variable_set("@#{k}", p.fetch(k, nil))
          self.class.__send__(:attr_accessor, k)
        end
      end
    end
    

    发生了什么,是我们将提供给initialize 方法的参数(哈希p),获取它的键并从中创建实例变量,为每个变量分配与键对应的值。然后我们为每个键定义attr_accessor

    a = Foo.new(a: 2, b: 3)
    #=> #<Foo:0x00000002d63ad8 @a=2, @b=3>
    

    【讨论】:

    • 这看起来与我想的可能是警察出局相似。双关语意。虽然我同意这是解决问题的一种方法,但您是否可以指出我的参考,以便我可以阅读更多关于为什么这是“正确”方法的信息?感谢您抽出宝贵时间回复!
    • @CarlyL 关于正确的方式 - Ruby 是一种非常灵活的语言,因此可以通过多种方式完成工作。通常,“正确的方式”是个人喜好的问题。我认为您可以通读 Ruby 样式指南以了解该做什么,但我怀疑有人会声称某事是 100% 正确的 :)
    • 您也可以将属性的名称放在一个冻结数组中,例如ATTR_NAMES = %i(one two three four five six seven eight).freeze 常量并调用attr_accessor(*ATTR_NAMES)
    【解决方案2】:

    您不应将每个变量分配为不同的变量。您应该将其作为单个散列保存到变量中,并在需要值时访问散列。事实上,你似乎已经有了一个变量p。所以保留为@p = p

    【讨论】:

    • 感谢您抽出宝贵时间回复。两种回答都说我只能有一个 attr_accessor p ,它是一个哈希值,但这对我来说似乎有点奇怪。你有什么我可以读到的参考资料,说明为什么这是最好的方法?
    猜你喜欢
    • 1970-01-01
    • 2020-05-22
    • 2016-04-13
    • 2019-10-17
    • 2021-06-16
    • 2023-04-07
    • 2015-09-05
    • 2022-06-20
    • 1970-01-01
    相关资源
    最近更新 更多