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