Great idea, and a nice syntax, Ara. Here's another implementation that isn't as efficient, but more "dynamic" than yours:
module Prototype
def self.new parent = nil, &blk
mod = Module.new do
include parent if parent
extend self
def clone
Prototype.new self
end
def method_missing name, *args
ivar = "@#{name}"
case args.size
when 0
obj = ancestors.find { |m| m.instance_variables.include? ivar }
if obj
obj.instance_variable_get ivar
else
super
end
when 1
instance_variable_set ivar, args.first
else
super
end
end
def do &blk
module_eval( &blk ) if blk
end
end
mod.do( &blk )
mod
end
end
It allows things like:
Obj = Prototype.new {
v 42
def show; p v end
}
Obj.show # => 42
Cld = Obj.clone
Cld.show # => 42
Cld.v 45
Cld.show # => 45
Obj.show # => 42
Obj.do {
x "x"
def m; p x; end
}
Obj.m # => "x"
Cld.m # => "x"