【问题标题】:Ruby Style/ClassVars cop confusionRuby Style/ClassVars 警察混乱
【发布时间】:2021-05-01 12:06:55
【问题描述】:

我正在与 Rubocop 的 Style/ClassVars 规则作斗争。它要我用一个类实例变量替换类变量@@mutex。这是代码,它执行一些非常慢的延迟初始化:

FastGettext.class_eval do
    attr_writer :mutex
    attr_accessor :locales
  
    def mutex
      # Style/ClassVars: Replace class var @@mutex with a class instance var.
      @@mutex ||= Mutex.new
    end
  
    def human_available_locales
      original_locale = FastGettext.locale
      mutex.synchronize do
        return locales if locales
        # perform loading and translating of locale names
        # (removed)
        locales
      end
    ensure
      FastGettext.locale = original_locale
    end
  end

Rails 有一个很好的助手attr_accessor_with_default,它允许定义一个具有默认值的访问器,但它已被弃用。弃用消息说,请改用 Ruby。我被卡住了,我真的不知道这段代码应该如何满足 Rubocop。通常,属性在构造函数中初始化,但这是一个类上下文。我需要初始化互斥体,最好是在类加载期间。

我最初的实现只有@@mutex@@locales,我不知道为什么 Rubocop 如此努力地推动这一点。我知道访问器很容易重载,但我知道这一点。要么我在这里遗漏了一些东西,要么这是一个默认启用的非常糟糕的警察。

感谢您的帮助

编辑:这是一个看起来仍然很奇怪的解决方案,但它确实有效:

      FastGettext.class_eval do
        attr_accessor :mutex, :locales
        self.mutex = Mutex.new

        def human_available_locales
          original_locale = FastGettext.locale
          mutex.synchronize do
            return locales if locales
            # ...
            locales
          end
        ensure
          FastGettext.locale = original_locale
        end
      end

【问题讨论】:

标签: ruby class-variables rubocop


【解决方案1】:

RuboCop 是对的。假设你有一个这样的继承类:

class VeryFastGettext < FastGettext
end

现在VeryFastGettext 与基类共享同一个互斥锁。这很少是期望的行为。

这是可以在合理的情况下安抚RuboCop的代码:

FastGettext.class_eval do
  def self.mutex
    @mutex ||= Mutex.new
  end

  def mutex
    self.class.mutex
  end
end

【讨论】:

  • 不能延迟初始化互斥锁,这是一个非原子操作。但是我找到了解决方案。谢谢。
猜你喜欢
  • 2023-03-31
  • 2012-09-14
  • 2017-08-08
  • 1970-01-01
  • 2015-11-30
  • 2020-09-28
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多