问题描述
我正在为 Rubocop 的 Style/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