Ruby Style/ClassVars 警察混淆

问题描述

我正在为 RubocopStyle/ClassVars 规则苦苦挣扎。它要我类实例 var 替换类 var @@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

解决方法

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...