Ruby Class instance

Igor Guzak
2 min readDec 29, 2019

--

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 # => Class
Class.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: true
String.new('a').object_id == String.new('a').object_id # => false
'a'.object_id == 'a'.object_id # => true

Next to read: Ruby Metaclass, Eigenclass, Singleton

--

--