I recently started learning ruby. I am confused between class methods, instance methods, instance variables, and class variables. I googled a lot, but I didn't get any clarification on those. Any help along with examples would be appreciated.
First take a look at this diagram:
You can rightly say that “obj has a method called my_method( ),” meaning that you’re able to call obj.my_method(). By contrast, you shouldn’t say that “MyClass has a method named my_method().” That would be confusing, because it would imply that you’re able to call MyClass.my_method() as if it were a class method.
To remove the ambiguity, you should say that my_method() is an instance method (not just “a method”) of MyClass, meaning that it’s defined in MyClass, and you actually need an instance of MyClass to call it. It’s the same method, but when you talk about the class, you call it an instance method, and when you talk about the object, you simply call it a method. Remember this distinction, and you won’t get confused when writing introspective code like this:
String.instance_methods == "abc".methods # => true String.methods == "abc".methods # => false
an object’s instance variables live in the object itself, and an object’s methods live in the object’s class. That’s why objects of the same class share methods but don’t share instance variables.
I am confused between class methods, instance methods,
There is no such thing as a "class method" in Ruby. There is exactly one kind of methods: instance methods.
Rubyists will sometimes talk about "class methods", but that is just a convenient name we use to refer to "instance methods of the singleton class of an instance of the Class class". That's quite a mouthful, and so we will abbreviate it to "class methods", but we know full well that class methods don't exist in the Ruby language.
instance variables, and class variables.
Really, the distinction is pretty much what it says on the tin: instance variables belong to objects (aka instances), whereas class variables belong to classes. Actually, class variables have pretty broad scope: a class variable is visible inside the class it is defined in, all of its instances, all of its subclasses, all instances of its subclasses, all of its subclasses' subclasses, all instances of all of its subclasses' subclasses and so on and so forth. Basically, class variables are visible through the entire class sub-hierarchy and all direct and indirect instances.
Note that classes are objects like any other, they are instances, too (of the Class class). Which means they can have instance variables as well, just like all other objects. 99% of the time, when you think you want a class variable, you actually want an instance variable of the class.
Related
So, from what I understand, in a class, a self.method is like a class method, whereas a regular method is like an instance method. But, as you can't instantiate a module, why would I use one over the other? What is the difference between these two in a module?
So, from what I understand, in a class, a self.method is like a class method, whereas a regular method is like an instance method.
That is not true. Ruby only has one single kind of method: instance methods. So, what you call a "regular method" is not "like" an instance method, it is an instance method. And there are no class methods in Ruby, every method is an instance method.
There are two ways to define a method in Ruby: with an explicit definee (def foo.bar) and without (def bar, which is then using the default definee).
In the first case, it is easy to know where a method will be defined: if you say def foo.bar, the method will become an instance method of foo's singleton class, always.
If you say def bar, the method becomes an instance method of the default definee, which usually, but not always, is the closest lexically enclosing module definition body. The most notable exception is a method that is defined directly in a script body, in this case, there is no lexically enclosing module definition, and the default definee is Object instead. In fact, there is even another twist: the method will be implicitly defined as private as well.
So, in your case, the first method will become an instance method of the singleton class of self (and inside a module definition body, self is the module itself), the second method will become an instance method of the module.
But, as you can't instantiate a module,
Ruby has a feature called inheritance. While it is true that you can directly instantiate a module, you can instantiate a class that inherits from a module. In fact, since the Object class inherits from the Kernel module (which has instance methods like Kernel#puts or Kernel#require, which may have used once or twice), and almost every class directly or indirectly inherits from Object, it is highly likely that you will have in your Ruby programming already have instantiated an indirect instance of a module and used a module's instance methods.
Enumerable is another important module in Ruby that contains methods like map, select, etc. that both Array and Hash inherit from.
why would I use one over the other?
There's really not much to it: you'd use an instance method, if you want to … well use an instance method, i.e. want to have a method that has privileged access to the internal representation of self across many different instances of the same module.
You would use a method of the singleton class, if you want the method to be only available for that single object.
There is one and only one reason for having module methods: to invoke those methods on the module in which they defined (using self: def self.my_method...). An example of this is Ruby's built-in Math module. All methods in this module are module methods. These methods are all invoked with Math as their explicit receiver (e.g., Math.sqrt(2.5)). In effect, they are used like functions in non-OO languages.
When you include, prepend or extend a module from a class, any module methods are simply ignored.
You might find this (timely) article helpful in understanding the Ruby object model and how methods are “looked up”: https://www.honeybadger.io/blog/ruby-method-lookup/
I am trying to call a method on File. I read the documentation of File and I see the class method ::basename. I tried the following:
x = File.new("name_of_file.ext")
x::basename("name_of_file.ext")
Why can't I access the class method ::basename in this way?
There is no such thing as a class method in Ruby. Classes are objects like any other object in Ruby. Like any other object in Ruby, they are instances of a class, namely the class Class.
So, just like any other object has methods that are defined in its class, classes also have methods that are defined in its class.
That's one half of the story. "Class methods" like ::new are typically like this. Class#new is an instance method of class Class, and since File is an instance of Class, you can call File.new.
The other half of the story is that every object in Ruby has a singleton class, a class that this object is the only instance of. Since this class has only one instance, any instance methods defined in this singleton class can only be called on that one single object. Since classes are objects like any other object, they have a singleton class like any other object, and methods can be defined there. For example, File::basename is defined as an instance method of the singleton class of File.
The reason why you cannot call x.basename is really simple: File and x are completely different objects which are instances of completely different classes, so why would you expect to be able to call the same method on both? Well, you wouldn't! Different objects that are instances of different classes usually have different methods.
I understand that all classes in ruby are instances of metaclass Class. And that "regular" objects are instances of these classes (the instances of metaclass Class).
But I keep wondering, I mean classes are root of objects, classes are themselves instances of Class (called metaclass because its instances are classes). I saw in some blogs some overriding of method new, of class Class.
So Class behaves as a class, but its instances are classes. So it seems we have a circle, it looks likes class Class is an instance of itself.
I'm clearly missing a point here. What is the origin of class Class?
Here's an example that's confusing me:
class Class
def new
#something
end
end
But keyword class implies an instance of class Class. So how do this work?
how do this work
Easy: it doesn't. Not in Ruby, anyway.
Just like in most other languages, there are some core entities that are simply assumed to exist. They fall from the sky, materialize out of thin air, magically appear.
In Ruby, some of those magic things are:
Object doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is always Object. [Note: there may be implementation-defined superclasses of Object, but eventually, there will be one which doesn't have a superclass.]
Object is an instance of Class, which is a subclass of Object (which means that indirectly Object is an instance of Object itself)
Class is a subclass of Module, which is an instance of Class
Class is an instance of Class
None of these things can be explained in Ruby.
BasicObject, Object, Module and Class all need to spring into existence at the same time because they have circular dependencies.
Just because this relationship cannot be expressed in Ruby code, doesn't mean the Ruby Language Specification can't say it has to be so. It's up to the implementor to figure out a way to do this. After all, the Ruby implementation has a level of access to the objects that you as a programmer don't have.
For example, the Ruby implementation could first create BasicObject, setting both its superclass pointer and its class pointer to null.
Then, it creates Object, setting its superclass pointer to BasicObject and its class pointer to null.
Next, it creates Module, setting its superclass pointer to Object and its class pointer to null.
Lastly, it creates Class, setting its superclass pointer to Module and its class pointer to null.
Now, we can overwrite BasicObject's, Object's, Module's, and Class's class pointer to point to Class, and we're done.
This is easy to do from outside the system, it just looks weird from the inside.
Once they do exist, however, it is perfectly possible to implement most of their behavior in plain Ruby. You only need very barebones versions of those classes, thanks to Ruby's open classes, you can add any missing functionality at a later time.
In your example, the class Class is not creating a new class named Class, it is reopening the existing class Class, which was given to us by the runtime environment.
So, it is perfectly possible to explain the default behavior of Class#new in plain Ruby:
class Class
def new(*args, &block)
obj = allocate # another magic thing that cannot be explained in Ruby
obj.initialize(*args, &block)
return obj
end
end
[Note: actually, initialize is private, so you need to use obj.send(:initialize, *args, &block) to circumvent the access restriction.]
BTW: Class#allocate is another one of those magic things. It allocates a new empty object in Ruby's object space, which is something that cannot be done in Ruby. So, Class#allocate is something that has to be provided by the runtime system as well.
There is a meta-circularity given by the "twist" link. It is the built-in superclass link from the root's eigenclass to the Class class. This can be expressed by
BasicObject.singleton_class.superclass == Class
A clue to understanding the .class map is seeing this map as derived from the eigenclass and superclass links: for an object x, x.class is the first class in the superclass chain of x's eigenclass. This can be expressed by
x.class == x.eigenclass.superclass(n)
where eigenclass is a "conceptual alias" of singleton_class
(resistant to issues with immediate values), y.superclass(i) means i-th superclass of y and n is smallest such that x.eigenclass.superclass(n) is a class. Equivalently, eigenclasses in the superclass chain of x.eigenclass are skipped (see rb_class_real which also reveals that in MRI, even superclass links are implemented indirectly – they arise by skipping "iclasses").
This results in that the class of every class (as well as of every eigenclass) is constantly the Class class.
A picture is provided by this diagram.
The metaclass confusion has 2 main sources:
Smalltalk. The Smalltalk-80 object model contains conceptual inconsistencies that are rectified by the Ruby object model. In addition, Smalltalk literature uses dialectics in terminology, which unfortunately has not been sufficiently remedied in the Ruby literature.
The definition of metaclass. At present, the definition states that metaclasses are classes of classes. However, for so called "implicit metaclasses" (the case of Ruby and Smalltalk-80) a much more fitting definition would be that of meta-objects of classes.
Yes, Class is an instance of itself. It's a subclass of Module, which is also an instance of class, and Module is a subclass of Object, which is also an instance of Class. It is indeed quite circular — but this is part of the core language, not something in a library. The Ruby runtime itself doesn't have the same limits thast you or I do when we're writing Ruby code.
I've never heard the word "metaclass" used to talk about Class, though. It isn't used much in Ruby at all, but when it is, it's usually a synonym for what's officially called a "singleton class of an object," which is an even more confusing topic than Object-Module-Class triangle.
Though it is a little out of date, this article by _why may help in understanding the behavior. You can find an even deeper dive into the subject in Paolo Perrotta's Metaprogramming Ruby.
I understand that all classes in ruby are instances of metaclass Class. And that "regular" objects are instances of these classes (the instances of metaclass Class).
But I keep wondering, I mean classes are root of objects, classes are themselves instances of Class (called metaclass because its instances are classes). I saw in some blogs some overriding of method new, of class Class.
So Class behaves as a class, but its instances are classes. So it seems we have a circle, it looks likes class Class is an instance of itself.
I'm clearly missing a point here. What is the origin of class Class?
Here's an example that's confusing me:
class Class
def new
#something
end
end
But keyword class implies an instance of class Class. So how do this work?
how do this work
Easy: it doesn't. Not in Ruby, anyway.
Just like in most other languages, there are some core entities that are simply assumed to exist. They fall from the sky, materialize out of thin air, magically appear.
In Ruby, some of those magic things are:
Object doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is always Object. [Note: there may be implementation-defined superclasses of Object, but eventually, there will be one which doesn't have a superclass.]
Object is an instance of Class, which is a subclass of Object (which means that indirectly Object is an instance of Object itself)
Class is a subclass of Module, which is an instance of Class
Class is an instance of Class
None of these things can be explained in Ruby.
BasicObject, Object, Module and Class all need to spring into existence at the same time because they have circular dependencies.
Just because this relationship cannot be expressed in Ruby code, doesn't mean the Ruby Language Specification can't say it has to be so. It's up to the implementor to figure out a way to do this. After all, the Ruby implementation has a level of access to the objects that you as a programmer don't have.
For example, the Ruby implementation could first create BasicObject, setting both its superclass pointer and its class pointer to null.
Then, it creates Object, setting its superclass pointer to BasicObject and its class pointer to null.
Next, it creates Module, setting its superclass pointer to Object and its class pointer to null.
Lastly, it creates Class, setting its superclass pointer to Module and its class pointer to null.
Now, we can overwrite BasicObject's, Object's, Module's, and Class's class pointer to point to Class, and we're done.
This is easy to do from outside the system, it just looks weird from the inside.
Once they do exist, however, it is perfectly possible to implement most of their behavior in plain Ruby. You only need very barebones versions of those classes, thanks to Ruby's open classes, you can add any missing functionality at a later time.
In your example, the class Class is not creating a new class named Class, it is reopening the existing class Class, which was given to us by the runtime environment.
So, it is perfectly possible to explain the default behavior of Class#new in plain Ruby:
class Class
def new(*args, &block)
obj = allocate # another magic thing that cannot be explained in Ruby
obj.initialize(*args, &block)
return obj
end
end
[Note: actually, initialize is private, so you need to use obj.send(:initialize, *args, &block) to circumvent the access restriction.]
BTW: Class#allocate is another one of those magic things. It allocates a new empty object in Ruby's object space, which is something that cannot be done in Ruby. So, Class#allocate is something that has to be provided by the runtime system as well.
There is a meta-circularity given by the "twist" link. It is the built-in superclass link from the root's eigenclass to the Class class. This can be expressed by
BasicObject.singleton_class.superclass == Class
A clue to understanding the .class map is seeing this map as derived from the eigenclass and superclass links: for an object x, x.class is the first class in the superclass chain of x's eigenclass. This can be expressed by
x.class == x.eigenclass.superclass(n)
where eigenclass is a "conceptual alias" of singleton_class
(resistant to issues with immediate values), y.superclass(i) means i-th superclass of y and n is smallest such that x.eigenclass.superclass(n) is a class. Equivalently, eigenclasses in the superclass chain of x.eigenclass are skipped (see rb_class_real which also reveals that in MRI, even superclass links are implemented indirectly – they arise by skipping "iclasses").
This results in that the class of every class (as well as of every eigenclass) is constantly the Class class.
A picture is provided by this diagram.
The metaclass confusion has 2 main sources:
Smalltalk. The Smalltalk-80 object model contains conceptual inconsistencies that are rectified by the Ruby object model. In addition, Smalltalk literature uses dialectics in terminology, which unfortunately has not been sufficiently remedied in the Ruby literature.
The definition of metaclass. At present, the definition states that metaclasses are classes of classes. However, for so called "implicit metaclasses" (the case of Ruby and Smalltalk-80) a much more fitting definition would be that of meta-objects of classes.
Yes, Class is an instance of itself. It's a subclass of Module, which is also an instance of class, and Module is a subclass of Object, which is also an instance of Class. It is indeed quite circular — but this is part of the core language, not something in a library. The Ruby runtime itself doesn't have the same limits thast you or I do when we're writing Ruby code.
I've never heard the word "metaclass" used to talk about Class, though. It isn't used much in Ruby at all, but when it is, it's usually a synonym for what's officially called a "singleton class of an object," which is an even more confusing topic than Object-Module-Class triangle.
Though it is a little out of date, this article by _why may help in understanding the behavior. You can find an even deeper dive into the subject in Paolo Perrotta's Metaprogramming Ruby.
I understand that this question has been raised many times already. But I can't find the complete guide about all those kinds of variables. I've found a couple of articles that compare class variables vs class instance variables, but what about instance variables?
So, what is the difference between: instance variables, class variables and class instance variables? What kind of variables are inheritable and what are not?
An instance variable is, well, a variable that belongs to one specific object (aka instance). Inheritance is irrelevant in this case, since objects can't inherit from anything, only classes can.
Class instance variables don't exist. Classes are objects just like any other, so they can have instance variables just like any other object. When a class has an instance variable, this is sometimes called a class instance variable, but it's just an instance variable. So, again, it can't be inherited.
Class variables are strange beasts. They are shared among
the class itself
all instances of the class
all subclasses of the class
all instances of all subclasses of the class
all subclasses of all subclasses of the class
all instances of all subclasses of all subclasses of the class
… and so on …
They are really more like global variables, considering how widely they are shared.
You can call this sharing inheritance, but I don't think that's a useful term. There is no polymorphic dispatch, no message sending, no overriding.
In Ruby, the term inheritance really only makes sense with methods, not with variables.
Instance Variables are variables which are the ones whose data varies with each instance of the object.
Class variables are those which are shared across all instances of a class. Actually every instance points to the same value and change is seen across all the class instances.