NAME prototype.rb INSTALL gem install prototype URIS http://rubyforge.org/projects/codeforpeople/ http://codeforpeople.com/lib/ruby/ SYNOPSIS prototype.rb facilitates a prototype based coding style http://en.wikipedia.org/wiki/Prototype-based_programming for ruby WHY prototype based programming looks very nice ;-) also, there are many problems that a genuine singleton object with cloning abilities can illuminate clearly it's the basis of a new rendering model for rails HISTORY 2.0.0 completely gutted the prototype library and re-implemented with a module/singleton_class/include approach. note that this version increases a major number because it is NOT compatible with past releases. the incompatible change is that 'clone' now returns an object that does not reflect changes made to the parent: it is completely independant. 1.0.0 cleanup up a small error where bareword syntax errors in a prototype block were silently ignored SAMPLES <========< samples/a.rb >========> ~ > cat samples/a.rb require 'prototype' singleton = Prototype.new{ @a, @b = 40, 2 def answer() @a + @b end } p singleton.answer #=> 42 ~ > ruby samples/a.rb 42 <========< samples/b.rb >========> ~ > cat samples/b.rb require 'prototype' DB = Prototype.new{ host 'localhost' port 4242 conn_string [host, port].join(':') def connect() p [host, port] end } p DB.host #=> "localhost" p DB.port #=> 4242 p DB.conn_string #=> "localhost:4242" DB.connect #=> ["locahost", 4242] ~ > ruby samples/b.rb "localhost" 4242 "localhost:4242" ["localhost", 4242] <========< samples/c.rb >========> ~ > cat samples/c.rb require 'prototype' a = Prototype.new{ def method() 42 end } b = a.clone p a.method #=> 42 p b.method #=> 42 a.extend{ def method2() '42' end } p a.respond_to?(:method2) #=> true p b.respond_to?(:method2) #=> false b.extend{ def method3() 42.0 end } p a.respond_to?(:method3) #=> false p b.respond_to?(:method3) #=> true ~ > ruby samples/c.rb 42 42 true false false true <========< samples/d.rb >========> ~ > cat samples/d.rb require 'prototype' proto = prototype{ attributes 'a' => 1, 'b' => 2, 'c' => 3 } proto = prototype{ a 1; b 2; c 3 } %w( a b c ).each{|attr| p proto.send(attr)} #=> 1, 2, 3 clone = proto.clone proto.c = 42 %w( a b c ).each{|attr| p proto.send(attr)} #=> 1, 2, 42 %w( a b c ).each{|attr| p clone.send(attr)} #=> 1, 2, 3 ~ > ruby samples/d.rb 1 2 3 1 2 42 1 2 3 <========< samples/e.rb >========> ~ > cat samples/e.rb require 'prototype' proto = Object.prototype{ @a = 40 @b = 2 } p(proto.a + proto.b) #=> 42 ~ > ruby samples/e.rb 42 <========< samples/f.rb >========> ~ > cat samples/f.rb require 'prototype' a = Object.prototype{ attributes 'a' => 4, 'b' => 10, 'c' => 2} b = Object.prototype{ a 4; b 10; c 2 } c = Object.prototype{ @a = 4; @b = 10; @c = 2 } [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) } #=> 42, 42, 42 ~ > ruby samples/f.rb 42 42 42 <========< samples/g.rb >========> ~ > cat samples/g.rb require 'prototype' a = prototype{ @a, @b, @c = 4, 10, 2 } b = a.clone b.extend{ def answer() a * b + c end } p b.answer #=> 42 ~ > ruby samples/g.rb 42 <========< samples/h.rb >========> ~ > cat samples/h.rb require 'prototype' proto = prototype{ a 1 b 1 c 40 sum { a + b + c } } p proto.sum #=> 42 ~ > ruby samples/h.rb 42 <========< samples/i.rb >========> ~ > cat samples/i.rb require 'prototype' o = Object.new o.prototyping do @a = 42 attr 'a' end p o.a o = prototype do @a = 42 attr 'a' end p o.a o.prototyping do @b = 42 attr 'b' end p o.b o.prototyping do @b = 42.0 end p o.b ~ > ruby samples/i.rb 42 42 42 42.0