Skip to content

Instantly share code, notes, and snippets.

@floere
Created April 15, 2009 21:31
Show Gist options
  • Save floere/96033 to your computer and use it in GitHub Desktop.
Save floere/96033 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'activesupport'
class Object
# As popularized by Why:
# http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
#
def metaclass
class << self; return self; end
end
# Let's def def.
#
def def name, &block
metaclass.send :define_method, name, &block
end
# Finally, the ability to define new classes.
# Note: See the end of the article for API ideas.
#
def class name, superclass = Object, namespace = '', &block
namespace.to_s.constantize.const_set name, Class.new(superclass, &block)
end
end
class Class
# Let's install a convenience method that is installed
# on all instances of this Class.
#
def def_on_all_instances name, &block
send :define_method, name, &block
end
end
# Let's see how we would use def on a Class.
#
Monkey = Class.new
Monkey.def :interests do
"Monkeys love bananas, and tightly coupled code."
end
puts Monkey.interests
# Let's see how we would use def on a single instance.
#
m = Monkey.new
m.def :demonstrate do
"The monkey tries to run his code. And fails."
end
puts m.demonstrate
# This monkey cannot demonstrate.
#
n = Monkey.new
puts "Well, could his younger brother demonstrate? #{n.respond_to?(:demonstrate) ? 'Yes.' : 'No. Only older brother monkey can.' }"
# Let's define a method for all instances Monkey has produced and will produce.
#
Monkey.def_on_all_instances :sulk do
"Monkey is sulking. Well, monkey, if you just would listen and decouple your code!"
end
puts m.sulk
puts Monkey.new.sulk # So, all monkeys know how to sulk.
# How about class?
#
self.class :Chimp do
def self.skreech
puts 'Eeek!'
end
end
Chimp.skreech
# And namespacing?
#
Apes = Module.new
self.class :Chimp, Object, :Apes do
def self.skreech
puts 'Eeek!'
end
end
Apes::Chimp.skreech
# How about subclassing?
#
self.class :ArraySubclass, Array do
end
puts ArraySubclass.superclass
# API idea
# self.class 'Apes::Chimp', Apes::Base do
# ...
# end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment