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.
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 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.
This question already has answers here:
Ruby metaclass confusion
(4 answers)
Closed 7 years ago.
I don't quite get some things about the Ruby object model. First, is EVERYTHING in Ruby an instance of Class? These all produce true:
p Object.instance_of?(Class)
p Class.instance_of?(Class)
p Module.instance_of?(Class)
p BasicObject.instance_of?(Class)
class Hello; end
p Hello.instance_of?(Class)
I can't quite get how is it possible, if Object is a superclass of Class, how can it be both a superclass of Class and an instance of it at the same time (most diagrams on the Ruby Object Model clearly state this hierarchy)? Which allows for some crazyness like this:
p BasicObject.is_a?(Object) #=> true
where BasicObject.class is Class, and Class.is_a?(Object).
By the way, using Ruby 2.0.
First, is EVERYTHING in Ruby an instance of Class?
No, not everything is an instance of Class. Only classes are instances of Class.
There are lots of things which aren't instances of Class: strings, for example, are instances of String, not Class. Arrays are instances of Array, integers are instances of Integer, floats are instances of Float, true is an instance of TrueClass, false is an instance of FalseClass, nil is an instance of NilClass, and so on.
Every class is an instance of Class, just like every string is an instance of String.
if Object is a superclass of Class, how can it be both a superclass of Class and an instance of it at the same time (most diagrams on the Ruby Object Model clearly state this hierarchy)?
Magic.
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.
You should notice that:
p BasicObject.instance_of?(BasicObject)
prints false.
That is, the expression BasicObject is not an instance of BasicObject, it is an instance of something else, that is, it is a Class object, which represents an object that holds (for example) the class methods, such as new.
For example:
p (BasicObject.new()).instance_of?(BasicObject)
prints true, and
p (BasicObject.new()).instance_of?(Class)
prints false.
All of your examples were by definition classes. Classes are also objects. But what you didn't do was look at an instance of a class:
p Object.new.class
p Hello.new.class
Classes define the form of an object, and by definition, a class is a Class. But when you instantiate class into an object, the object is the new type. But you can still see that the object's class is itself Class:
p Hello.new.class.class
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'm reading 'metaprogramming in ruby'
its such an EXCELLENT book. Seriously, it talks about stuff that I never hear mentioned elsewhere.
I have a few specific questions however about objects (I'm in the first few chapters)
I understand that the RubyGems gem installs the method 'gem' to the module Kernel so that it shows up on every object. Is there a reason they didnt put it into the Object class?
He talks about how when ruby looks for the method it always goes right then up. What exactly does 'up' mean? I see it in the diagram, its just that I dont really understand the purpose of 'up'. he doesnt explain that part much.
What is the point of the Object class? How come those methods cant be just placed into Class? If every object belongs to a class (even if its Class), then what is the point of object, basicobject, and kernel?
String, Array, blah blah are obviously an instance of Class. Class is also an instance of itself. So if Class is an instance of Class.... how does it also inherit from Object? Where in the code does it relates to BOTH Class and Object?
I know kernel contains methods such as puts that can be used everywhere, and this relates to question 1, but why cant they just condense it and put it all into Object... where it would seem everything inherits from object anyway
Both would work, but typically methods on Object should only be methods that deal with a particular object. Puting things in the Kernel module are less about about object and more global.
I assume it means "up the inheritance chain". So it looks for the method on the child class, then on that classes parent class until it finds one or runs out of parent classes.
Object is the base class of all objects, naturally (For ruby 1.8 at least). The crazy part is that a class is actually an instance of the Class class. (you follow that?) So adding instance methods to Class would add methods to class objects, but not instances of those classes.
Nearly everything in ruby is an object. Class.superclass is actually Module (which is like a class you can't instantiate) and Module.superclass returns Object. So Class < Module < Object is the inheritance chain if the Class class. (For ruby 1.8 at least)
More convention than anything. Since Object can get rather HUGE, it's customary to put things into modules and then combine those modules later. If the method doesn't deal with an instance of an object directly as self then the method doesn't belong directly in Object. More global non-object instance methods like gem go in the Kernel module to signify that they are simply methods available everywhere.
Some more about class objects and inheritance...
class Foo < Bar
def hi
puts 'Hi!'
end
end
What this does is really quite awesome. It defines a class object, of course. Now this class object is configured to have a name Foo, a parent class Bar and a method hi. This info is sort of like this class object's meta data.
Now the class object Foo itself is an instance of Class. But Foo defines a class that inherits from Bar. The Class class defines a data structure to store this meta data about a class.
You can think of the Class class sorta kinda being defined like this:
class Class < Module
# fictional method called on class creation
def set_meta_data(name, superclass, methods)
#name = name
#superclass = superclass
#methods = methods
end
# fictional way in which an instance might be created
def new
instance = Object.new
instance.superclass = #superclass
instance.addMethods(#methods)
instance
end
end
So a class object itself would inherit from Class but it would create objects that do not.
Thinking of classes as objects can be a bit mind bending in this way, but this also why ruby is awesome.
For 1 and 5, pseudo-keyword commands tend to go into Kernel rather than Object.
For 2, it makes sense for sub-classes to be "down" relative to their parent class (sub literally meaning "beneath"). Therefore if you're heading for a parent class and its ancestors, you have to go "up".
For 3, an object object is not an instance of Class, it is an instance of Object.
For 4, what's wrong with something being an instance of Class and inheriting from Object? All classes inherit from Object.