Kelas Singleton di Ruby

# Everything in Ruby is an `Object`, even classes, modules and methods.
# Despite that, an `Object` can't exist without a class.
# Classes are instances of the `Class` class.
# The `Class` class is an instance of `Class` :). It holds a reference 
# to itself.

# All objects are instances of the `Object` class. `Object` itself
# is a class, so its an instance of the `Class` class.
# Despite that `Class` inherits from `Module` which
# in turn inherits from `Class`.

# It's very intertwined because the building blocks of Ruby
# so `Object`, `Module` and `Class`
# all reference each other in an endless loop.

# Only instances of `Module` and `Class` can hold methods in Ruby.
# Objects themselves don't hold any direct references to their methods.
# They only possess a reference to their class, from which they
# take their instance methods.

# Despite that, it's possible to extend objects with custom methods that
# are only available to that particular object.
# That's when the `singleton`, `eigen` or `meta` class comes in.

# (Almost) every Ruby object has two classes!
# One of them is the regular class available by the `#class` method,
# which holds instance methods of the object.
# The other class is available by the `#singleton_class` method.
# This class holds methods that are only available to this object.
# Every Ruby object has a unique singleton class. That's why methods
# defined in it are only available to one object.

class Foo
  	def some_instance_method
		puts "it's me, some_intance_method"
 	end
end

foo = Foo.new
foo.some_instance_method #=> it's me, some_intance_method

# you can define singleton methods
# (methods unique to a particular object)
# like so

def foo.unique_method
 	puts "I'm unique!"
end

# it's only available to that particular object
foo.unique_method #=> "I'm unique"
Foo.new.unique_method #=> undefined method `unique_method' (NoMethodError)

# the unique method is not a regular method
foo.methods.include?(:unique_method) #=> false
# it's a singleton methods
foo.singleton_methods #=> [:unique_method]
# which means that it's defined on the singleton class
foo.singleton_class.instance_methods.include?(:unique_method) #=> true

# there is an alternative syntax which let's you open the body
# of a singleton class directly and call/define methods on it

class << foo
	def another_singleton_method
    	puts "I'm another_singleton_method"
    end
    
    # since it's the singleton classes body
    # you can call class methods on it
    attr_accessor :bar
end

foo.singleton_methods
#=> [:unique_method, :another_singleton_method, :bar]
foo.bar = 3
foo.bar #=> 3
Mateusz Drewniak