rubyclassoop

What happens if I assign to a variable inside a Ruby class definition?


class A
    a = 1
end

In the above code, what happens to a? For example in Python, it becomes a class variable that can be accessed as A.a. However in Ruby, I don't know how to access it - attempts to do so in the enclosing scope as a, A.a and A.new.a all give errors:

undefined local variable or method `a` for main (NameError)
undefined method `a` for class A (NoMethodError)
undefined method `a` for an instance of A (NoMethodError)

Solution

  • The local variable a is in scope for the duration of the scope, in this case while the class definition is executing until the end of the class.

    This is because in Ruby, all code is executed from top to bottom, including class definitions which allows you to do things like

    class Foo
      var = :hello
      attr_accessor var
    end
    
    foo = Foo.new
    foo.hello = "world"
    foo.hello
    # => "world"
    

    Ruby knows class variables which are prefixed by double-@ characters, e.g. @@var. These are valid for a class, all of the class's subclasses, and their objects. Generally, the use of class variables is discouraged due to the rather broad scope and the often unexpected semantics of value sharing in sub-classes.

    Instead, you would often use an instance variable of a class's singleton class (which is sometimes also called eigenclass). This could be used like this:

    class Foo
      @foo = "foo"
      
      def self.foo
        @foo
      end
    
      def self.foo=(value)
        @foo
      end
    end
    
    class Bar < Foo
    end
    
    Foo.foo = "hello"
    Foo.foo
    # => "hello"
    
    Bar.foo
    # => nil