Proto = Class.new(Class) # Beware: magic.
def Proto.clone
Class.new(self)
end
####
class PrototypeClass
attr_reader :prototype
def initialize (prototype)
@prototype = prototype
end
def new (*definitions)
new_class = Class.new(self.class)
# With a modern Ruby you could use caller to find the
# file and line, then pass it in to give better error reporting.
for definition in definitions
new_class.module_eval definition
end
return new_class.new(self)
end
def def (definition)
# With a modern Ruby you could use caller to find the
# file and line, then pass it in to give better error reporting.
self.class.module_eval "def #{definition} end"
end
def include (*mod)
self.class.module_eval "include #{mod,join ', '}"
end
end
Prototype = PrototypeClass.new(nil)
##
##
@foo = Prototype.new %q{
attr_accessor :name
}
@bar = @foo.new
@baz = @bar.new
@foo.name = "foo"
@bar.name = "bar"
@baz.name = "baz"
def test_greet
try_greet = lambda {|obj|
if obj.respond_to? :greet
obj.greet(obj.name)
else
puts "Object #{obj.name} (#{obj.id}) cannot greet"
end
}
try_greet[@foo]
try_greet[@bar]
try_greet[@baz]
end
test_greet()
@bar.def %q{ greet (name)
puts "Greeting from #{name} (id #{self.id})"
}
puts "Defined bar.greet"
test_greet()
module Mod
def greet (name)
puts "Hello from #{name} (#{self.id})"
end
end
@foo.include(Mod)
puts "Included module"
test_greet()