Skip to content

Instantly share code, notes, and snippets.

@rosylilly
Created April 12, 2009 16:41
Show Gist options
  • Save rosylilly/94056 to your computer and use it in GitHub Desktop.
Save rosylilly/94056 to your computer and use it in GitHub Desktop.
Prototypical Objects on ruby
class Prototype
def new(member = {}, &block)
prototype(member || {}, self,&block)
end
def respond_to?(name)
return self if methods.include?(name.to_s)
__proto__ = @proto.respond_to?(name)
return __proto__ if __proto__
false
end
def method_missing( _method, *_arg, &block)
if __proto__ = @proto.respond_to?(_method)
__proto__ = @proto if __proto__ == true
__proto__.method(_method).call(*_arg,&block)
else
if _method.to_s[_method.to_s.length - 1].chr == '='
instance_variable_set( "@#{_method.to_s[ 0..._method.to_s.length - 1]}", _arg[0])
self.class.class_eval("attr_accessor :#{_method.to_s[ 0..._method.to_s.length - 1]}")
else
if block_given?
self.class.class_eval do
define_method( _method.to_sym, &block)
end
else
raise NoMethodError
end
end
end
end
attr_reader :proto
end
def prototype(member = {}, _proto_ = nil, &defs)
_class = Class.new(Prototype)
_class.class_eval(&defs) if block_given?
instance = _class.new
instance.instance_variable_set( :@proto, _proto_)
(member || {}).each_pair do | key, val |
instance.instance_variable_set( :"@#{key.to_s}", val)
_class.class_eval("attr_accessor :#{key}")
end
instance
end
a = prototype({:foo => "foo" }, "String")
puts a.inspect
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment