#http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
class Object
# The hidden singleton lurks behind everyone
def metaclass; class << self; self; end; end
def meta_eval(&blk)
metaclass.instance_eval(&blk)
end
# Adds methods to a metaclass
def meta_def name, &blk
meta_eval { define_method name, &blk }
end
# Defines an instance method within a class
def class_def name, &blk
class_eval { define_method name, &blk }
end
end
class A
def cheese
'shropshire blue'
end
def self.cheese
'edam'
end
end
class B < A
def cheese
'cheddar'
end
def self.cheese
'stilton'
end
end
a = A.new
b = B.new
b_with_meta = B.new
b_with_meta.meta_def(:cheese) {'cheshire'}
b_with_meta_meta = B.new
b_with_meta_meta.meta_def(:cheese) {'brie'}
b_with_meta_meta.metaclass.meta_def(:cheese) {'gouda'}
b_with_meta_meta.metaclass.metaclass.meta_def(:cheese) {'wensleydale'}
puts "A.cheese: #{A.cheese}"
puts "B.cheese: #{B.cheese}"
puts "a.cheese: #{a.cheese}"
puts "b.cheese: #{b.cheese}"
puts "b_with_meta.cheese: #{b_with_meta.cheese}"
puts "b_with_meta.metaclass.cheese: #{b_with_meta.metaclass.cheese}"
puts "b_with_meta_meta.cheese: #{b_with_meta_meta.cheese}"
puts "b_with_meta_meta.metaclass.cheese: #{b_with_meta_meta.metaclass.cheese}"
puts "b_with_meta_meta.metaclass.metaclass.cheese: #{b_with_meta_meta.metaclass.metaclass.cheese}"