ruby: class instance variables vs instance variables

半世苍凉 提交于 2019-11-27 02:06:55

it was very confusing for me to find out that @variable may mean 2 very different things.

No, it doesn't. Classes are objects just like any other object. They can have instance variables just like any other object. They can have instance methods just like any other object. In fact, unlike Java, which has three different kinds of "methods" (instance methods, static methods and constructors), in Ruby, there is exactly one kind of method: instance methods.

The beauty of having classes being objects is precisely that @variable always means exactly the same thing.

There is no such thing as a class instance variable: it's just a normal instance variable like any other. The object happens to be an instance of Class, but that doesn't change the nature of the instance variable. An instance variable of an object of class String is not a string instance variable, it's just an instance variable. Likewise, an instance variable of an object of class Class is just an instance variable.

There is no such thing as a class method: it's just a normal singleton method of an object which happens to be an instance of Class. (Acually, there's no such thing as a singleton method either: it's just a normal instance method of the object's singleton class.)

Note: Rubyists may use the term "class method" in casual conversation. But that doesn't mean that class methods actually exist, it only means that "instance method of the class object's singleton class" is a mouthful. The important thing is: because classes are objects, they work exactly like all other objects. They can have instance methods (defined in class Class or inherited from Module, Object, Kernel or BasicObject), they can have "singleton methods" (which really are instance methods of their respective singleton classes), they can have instance variables.

They can also have class variables (@@variables) … those are weird. Ignore them :-)

  1. First, to understand instance variables, one need to know this - classes are objects.

    All classes are instances of Class(read the doc) which inherits from Object. That's why classes are objects.

  2. Then, every instance variables(ids marked with @, like @ins) are defined in self.

    When self is a class, they are instance variables of classes(class instance variables). When self is a object, they are instance variables of objects(instance variables).

  3. In different code scopes, the self represents different things.

    class Test
      # class scope, uncomment following line to see the value of self
      # p self
      @ins = "gah"
      def self.ins
        # class scope
        # p self
        puts @ins
      end
    
      def initialize()
        # object scope
        # p self
        @ins = "wtf?"
      end
      def ins2
        # object scope
        # p self
        puts @ins
      end
    end
    
Josh Bodah

Everything looks right to me.

A class variable will be passed down through inheritance while an instance variable on a class will not. (src: Ruby class instance variable vs. class variable)

As far as design goes, I tend to prefer avoiding class variables altogether (I'd rather use a singleton), but if I had to choose one I would probably choose a class variable over a class instance variable to avoid confusion.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!