Skip to content

Instantly share code, notes, and snippets.

@brixen
Created October 7, 2009 23:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brixen/204542 to your computer and use it in GitHub Desktop.
Save brixen/204542 to your computer and use it in GitHub Desktop.
#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}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment