Search code examples
rubyclass-variablesclass-instance-variables

Should I use class variables or class-instance variables for class static variables in Ruby?


class Something
    @@variable = 'Class variable'

    def give_me
        @@variable
    end
end

class OtherThing
    @variable = 'Instance variable with an interface'

    class << self
        attr_accessor :variable
    end

    def give_me
        self.class.variable
    end
end

p Something.new.give_me
p OtherThing.new.give_me

What I want to know is, which one should I use? Which are the benefits and cons of each?

Class variables are:

  1. Private unless you make an interface
  2. Shared between inheritances
  3. Shorter to write

Class-instance variables are:

  1. Public, since you must use an interface to access them
  2. Not shared between inheritances, but are set to nil when inherited
  3. Longer to write

What else should I have in mind?


Solution

  • I recently discovered ActiveSupport defines class_inheritable_accessor, which does what the class-instance variables do with the advantage that objects are not shared across inheritance, and you can have a default value for the variable when subclassing.

    class Foo
      class_inheritable_accessor :x, :y
    end
    
    Foo.x = 1
    
    class Bar < Foo
    end
    
    Bar.x #=> 1
    Bar.x = 3
    Bar.x #=> 3
    Foo.x #=> 1
    

    More info here

    Just for completeness: of the two presented options, I prefer going with the class-instance variables, since is often the expected behavior.