Created
April 15, 2009 21:31
-
-
Save floere/96033 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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