【问题标题】:How to declare a class instance variable in Ruby?如何在 Ruby 中声明一个类实例变量?
【发布时间】:2014-03-04 23:38:11
【问题描述】:

我需要一个不会被继承的类变量,所以我决定使用一个类实例变量。目前我有这个代码:

class A
  def self.symbols
    history_symbols
  end

  private

  def self.history_tables
    @@history_tables ||= ActiveRecord::Base.connection.tables.select do |x|
      x.starts_with?(SOME_PREFIX)
    end
  end

  def self.history_symbols
    Rails.cache.fetch('history_symbols', expires_in: 10.minutes) do
      history_tables.map { |x| x.sub(SOME_PREFIX, '') }
    end
  end
end

我可以安全地将@@history_tables 转换为@history_tables 而不制动任何东西吗?目前我所有的测试都通过了,但我仍然不确定是否可以这样做。

【问题讨论】:

    标签: ruby-on-rails ruby refactoring class-variables class-instance-variables


    【解决方案1】:

    既然你想使用实例变量,你应该使用类的实例,而不是单例方法:

    class A
      def symbols
        history_symbols    
      end
    
      private
    
      def history_tables
        @history_tables ||= ActiveRecord::Base.connection.tables.select do |x|
          x.starts_with?(SOME_PREFIX)
        end
      end
    
      def history_symbols
        Rails.cache.fetch('history_symbols', expires_in: 10.minutes) do
          history_tables.map { |x| x.sub(SOME_PREFIX, '') }
        end
      end
    end
    
    A.new.symbols
    

    代替:

    A.symbols
    

    【讨论】:

    • 是的,这正是我所担心的。如何继续使用该类但仍阻止继承?
    • 为什么要阻止?你可以做class B < A; end
    • 如果history_tables 是一个类变量并且我有B < A 如果我在B 中更改history_tables 的值,它也会在A 中更改。我不希望这样。跨度>
    • @AlexPopov 不,因为您必须创建一个新实例,所以不能用另一个实例替换它。 A.new 您不能更改为 B。但是B.new 你仍然可以使用新的实例变量B.new.symbols 来做history_tables
    猜你喜欢
    • 2014-01-06
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多