Search code examples
rubyclass-variablesattr-accessor

Class variable using attr_accessor inside class << self


Can someone explain why self.foo= works outside of the class << self, while foo= does not work within the class << self.

class A
  class << self
    attr_accessor :foo
    foo = 'foo'
  end
end

p A.foo # => "nil"

class A
  class << self
    attr_accessor :foo
  end
  self.foo = 'foo'
end

p A.foo # => "foo"

This is not the same question as When to use 'self' in Ruby

To be clear, I am not asking when to use self. I am asking why I cannot set the class variable inside a 'class << self' block, but I can outside of it.


Solution

  • your second example isn't a class variable, it's a class instance variable to this class the proof is that if you inherited like this you'll get nil

    class A
      class << self
        attr_accessor :foo
      end
      self.foo = 'foo'
    end
    
    class B < A
    end
    
    B.foo # => nil
    

    So if you want to add a class variable in class << self you can use @@

    class A
    
      class << self
      @@foo = :foo
        def foo
          @@foo
        end
      end
    end