Reputation: 33
I have a class User
that inherits from ApplicationRecord. When I check User.ancestors.include?(Class)
, the result is false
but for User.class
, the result is Class
.
What's the use case for the information supplied by the class
method in such cases? What does it really tell me to be of practical use? It doesn't seem to have anything to do with inheritance.
Upvotes: 1
Views: 170
Reputation: 114208
What's the use case for the information supplied by the class method in such cases? What does it really tell me to be of practical use? It doesn't seem to have anything to do with inheritance.
class
works the same way for every object. Calling class
on a class provides the same information as calling class
on an instance. That's because in Ruby, classes are instances, too.
'foo'.class
returns String
because 'foo'
is an instance of String
. Likewise, User.class
returns Class
because User
is an instance of Class
.
In particular, User
is not an instance of ApplicationRecord
.
It might not be obvious that User
is an instance of Class
when creating it via the class
keyword:
class User < ApplicationRecord; end
But it becomes very obvious when you create it explicitly via Class.new
: (both examples produce the same result)
User = Class.new(ApplicationRecord)
User.class #=> Class
Because the above is just like: (using String.new
for demonstration purposes)
foo = String.new('foo')
foo.class #=> String
Upvotes: 2
Reputation: 3748
Classes in Ruby are first-class objects—each is an instance of class
Class
User
is an object of class Class
(which inherits from Object
).
class is an instance method of Object
. It returns the class of the object. Therefore, User.class
returns Class
. Every object will have this method, and it is useful to know what the object is (e.g., for debugging). Consider this code:
1.class
# => Fixnum
"q".class
# => String
The reason why User.ancestors
does not return Class
is because it returns the modules included in the module
. For example, Class.ancestors
will include Class
, but not User
because User
is an object of Class
, which includes its own modules.
Upvotes: 1
Reputation: 33
After reading another StackOverflow post, I realized that it can only be understood by keeping the following in mind:
User
class has a double role. It plays Class as well as Object.
If I wanted my User.class
to behave on the traditional lines (that is, User.class
shows ApplicationRecord
), then I have to override
it as follows:
class User
def self.class
self.superclass
end
end
Upvotes: 1
Reputation: 110725
User
is a class. All classes are instances of the class Class
(i.e., User.class #=> Class
). Therefore, all instance methods defined on Class
, or on Class
's ancestors, can be invoked on User
(i.e., every instance method of Class
is a class method of User
).
For example, one of Class
's instance methods is instance_methods
. One can therefore execute User.instance_methods
to obtain an array of User
's instance methods.
Upvotes: 2