Ruby Class instance
It’s well-known fact that everything in Ruby is an object or in other words instance of something, but it still could be confusing how class definitions and instances produced by them are about the same. In this post, I will try to make it cleaner.
class Person; end
This is the way how we create class in Ruby via using language syntax. At the same time, it is just a common way we create a new instance of Class
and assigning it to Person
variable, which is equal to:
Person = Class.new
Only instances of Class
have abilities to create new instances:
person = Person.new
And someone could raise a question — if only instances produced by Class
have the ability to create new instances then how we could explain the ability of having Class.new
and produce such instances too? So, there is a logical answer — Class
is the instance of Class
or itself;)
person.class # => Person
Person.class # => Class
Class.class # => ClassClass.object_id == Class.class.object_id # => true
The question of how
Class
could be an instance of them-self is rhetorical because it’s language implementation about which could be more discovered in Ruby source code, also there is an awesome book Ruby Under a Microscope: An Illustrated Guide to Ruby Internals.
Instances of Class
we simply call “classes” as places of definitions for our instances which they could produce, at the same time we name our “classes” with capital letter as Person
to highlight the fact that it’s Class
instance, but as it’s still an instance it could have any name:
person = Class.new # => #<Class:0x00005614bb425718>
Person = Class.new # => Person
The difference is only the way how such instance represent/print itself, so if we will ignore such customization there will be no difference:
Module.remove_method :inspectPerson # => #<Class:0x0000563455a4c920>
Class # => #<Class:0x000055a8aa2a1608>
Not every Class
instances have the ability to create new instances due to global uniqueness:
true.class # TrueClass
false.class # FalseClass
nil.class # NilClass
1.class # Integer
:something.class # Symbol:something.object_id == :something.object_id # => trueSymbol.new('something')
# => NoMethodError (undefined method `new' for Symbol:Class)
So, there is no sense in Symbol.new('something')
simply because Symbol
is not able to produce new instances one every invocation of new
. The same is true for boolean and number instances which are globally unique, so instance of Integer
such as 1
is always the same and there is no ability to create new 1
Integer.remove_method :inspect1 # => #<Integer:0x0000000000000003>
2 - 1 # => #<Integer:0x0000000000000003>
Also, there is some special case with such Class
instance as String
which always produce new instances when it’s done explicitly, but when we use literals in conjunction with magic comment # frozen_string_literal
the instance of string is reused (and it’s frozen so cannot be changed)
String.new('a').object_id == String.new('a').object_id # => false
'a'.object_id == 'a'.object_id # => false# with magic comment which need to be placed on top of your .rb file
# frozen_string_literal: trueString.new('a').object_id == String.new('a').object_id # => false
'a'.object_id == 'a'.object_id # => true
Next to read: Ruby Metaclass, Eigenclass, Singleton