# Prototype-2.0.0

**URL:** <https://www.ruby-forum.com/t/prototype-2-0-0/105975>\
**Category:** Ruby\
**Created:** [June 5, 2007, 5:33am UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975 "2007-06-05T05:33:54Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 5:33am UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/1 "2007-06-05T05:33:54Z")

</div>

NAME  
prototype.rb

INSTALL  
gem install prototype

URIS  
[http://rubyforge.org/projects/codeforpeople/](http://rubyforge.org/projects/codeforpeople/)  
[http://codeforpeople.com/lib/ruby/](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

```

enjoy

-a

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 8:56pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/2 "2007-06-05T20:56:38Z")

</div>

From: ara.t.howard [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Tuesday, June 05, 2007 6:33 AM

> NAME  
> prototype.rb

Several small questions about the library:

- Does cloned object has some connections with it’s prototype (as per  
Io:  
“prototype is something knowing how to process messages I don’t know”)

- If so, can object’s prototype be changed dynamically? (I mean, b.proto  
=  
c)

- And what about Io-like “prototype is context for code blocks?”:

block = lambda{puts a + b}

block.call #=\> undefined local variable or method `a’

p = Prototype.new{  
@a = 40  
@b = 2  
}

block.proto = p

bloc.call #=\> 42

BTW, Markaby uses complicated hack to “setup context variables, while  
building HTML” - which is very close to the above example.

- Does anybody uses it in real projects? I mean, does prototype-based  
approach in not prototype-based language have proved to be useful? The  
question is not about “throw the library away”, but about “who can say,  
what  
features in library are useful”, “who can recommend library for some  
tasks?”

V.

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 10:04pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/3 "2007-06-05T22:04:01Z")

</div>

On Jun 5, 2007, at 12:55 PM, Victor Zverok S. wrote:

> - Does cloned object has some connections with it’s prototype (as  
> per Io:  
> “prototype is something knowing how to process messages I don’t know”)

yes. if one does

clone = Object.prototype{ @a = 42 }.clone

the clone has a #a method from parent and @a instance var if it’s own

> - If so, can object’s prototype be changed dynamically? (I mean,  
> b.proto =  
> c)

no. but they can be extended

proto = Object.prototype

proto.prototyping do  
@a = 42

```
 def a() @a end

```

end

> block.proto = p
> 
> bloc.call #=\> 42

sortof.

cfp:~ \> cat a.rb  
require ‘prototype’

block = lambda{ puts a + b }

proto = Object.prototype

proto.prototyping do  
a 40  
b 2  
c &block  
end

proto.c

cfp:~ \> ruby a.rb  
42

i think your exact example would be quite easy to impliment

> BTW, Markaby uses complicated hack to “setup context variables, while  
> building HTML” - which is very close to the above example.

check out prototype.rb impl - it’s very clean imho. nothing is off  
limits - you can have attribute ‘id’, ‘name’, ‘object\_id’, etc and  
everything works.

> - Does anybody uses it in real projects? I mean, does prototype-based  
> approach in not prototype-based language have proved to be useful? The  
> question is not about “throw the library away”, but about “who can  
> say, what  
> features in library are useful”, “who can recommend library for  
> some tasks?”

example

Config = Object.prototype{  
YAML.load(IO.read(‘config’)).each do |key, value|  
attribute key =\> value  
end  
}

p Config.host  
p Config.port

i’m using it in several project where one might instead use a  
singleton. the advantage prototype gives you is basically that you  
can have a hierarchy of singletons, each inheriting state and  
behavior from it’s parent. i’m currently building a model-\>view (no  
controller) system for rails called ‘magnetic’ that hinges upon the  
ability to specify a hierarchy of properties and behavior over those  
properties and also that requires that each set of properties be a  
singleton (for performance reasons) and it’s filling that roll  
nicely. look for a release in the next few weeks.

kind regards.

-a

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 10:35pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/4 "2007-06-05T22:35:12Z")

</div>

From: ara.t.howard [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Tuesday, June 05, 2007 11:03 PM

> > Several small questions about the library:  
> > the clone has a #a method from parent and @a instance var if it’s own  
> > It’s understandable. I’ve meant the case

a = Object.prototype{ @x = 42 }

b = a.clone

a.extend {  
def my\_new\_method; puts “here!” end  
}

b.my\_new\_method #will b have ALL the methods of it’s prototype?

assert\_equal b.prototype, a #is there a way to obtain b’s prototype?

#we also can think this way:  
def b.method\_missing(:sym)  
self.prototype.send(:sym)  
end

I’m not prototype-based guru, of course.

What I want to say. I’ve started to think about prototype-based  
programming  
from Io and JavaScript. My very first impression was “I create objects,  
I  
clone objects, that’s all”. But further I’ve found, the more experienced  
people think about prototype-based as “each object has it’s prototype”  
first  
of all (which becames “object’s prototype processes all unknown  
signals”,  
“object’s prototype can be changed” and even Io’s “prototype defines  
lexical  
scope”).

It seems prototype.rb now does something like “my first impression”, not  
“prototype-based entirely”.

Am I wrong?

V.

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 10:21pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/5 "2007-06-05T22:21:05Z")

</div>

On Jun 5, 2007, at 3:03 PM, ara.t.howard wrote:

> example
> 
> Config = Object.prototype{  
> YAML.load(IO.read(‘config’)).each do |key, value|  
> attribute key =\> value  
> end  
> }
> 
> p Config.host  
> p Config.port

Which is significantly better than:

require “ostruct”  
Config = OpenStruct.new(  
File.open(“config”) { |file| YAML.load(file) }  
)

?

I guess the difference comes in how they are used, right? Can you  
show an example of that?

I realize I’m just not prototype enlightened yet. No offense intended.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 11:49pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/6 "2007-06-05T23:49:19Z")

</div>

On Jun 5, 2007, at 2:33 PM, Victor “Zverok” Shepelev wrote:

> > > >
> 
> a.extend {  
> def my\_new\_method; puts “here!” end  
> }
> 
> b.my\_new\_method #will b have ALL the methods of it’s prototype?

the first impl did indeed to that. the latest does not. i found it  
flew in the face of ‘normal’ ruby design patterns - which is where  
i’m using it after all! 😉

> assert\_equal b.prototype, a #is there a way to obtain b’s prototype?

hmmm. i think the closest thing would be

assert a.class === b

prototype sets up what you would consider a ‘normal’ ruby hierarchy.  
that is to say clones are created from a subclass of the cloner’s class.

> #we also can think this way:  
> def b.method\_missing(:sym)  
> self.prototype.send(:sym)  
> end
> 
> I’m not prototype-based guru, of course.

me neither!

> “object’s prototype can be changed” and even Io’s “prototype  
> defines lexical  
> scope”).
> 
> It seems prototype.rb now does something like “my first  
> impression”, not  
> “prototype-based entirely”.
> 
> Am I wrong?

you are right. i may look into making it closer to the latter in the  
future.

kind regards.

-a

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 11:46pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/7 "2007-06-05T23:46:19Z")

</div>

On Jun 5, 2007, at 2:19 PM, James Edward G. II wrote:

> > > can say, what
> 
> ?  
> yes, i think so:

cfp:~ \> cat a.rb  
require ‘rubygems’  
require ‘prototype’  
require ‘ostruct’  
require ‘yaml’

hash = {  
:id =\> 42,  
:send =\> ‘removed\_email\_address@domain.invalid’,  
:class =\> ‘first’,  
}

running ‘prototype’ do  
config = prototype.configured hash  
p config.id  
p config.send  
p config.class  
end

running ‘ostruct’ do  
config = OpenStruct.new hash  
p config.id  
p config.send  
p config.class  
end

BEGIN {  
def running name  
puts “\<======== #{ name } ========”  
begin  
yield  
rescue =\> e  
m, c, b = e.message, e.class, e.backtrace.join("\n")  
puts “#{ m }(#{ c })\n#{ b }”  
ensure  
puts  
end  
end  
}

cfp:~ \> ruby a.rb  
\<======== prototype ========  
42  
“removed\_email\_address@domain.invalid”  
“first”

\<======== ostruct ========  
a.rb:21: warning: Object#id will be deprecated; use Object#object\_id  
125270  
no method name given(ArgumentError)  
a.rb:22:in `send' a.rb:22 a.rb:31:in`running’  
a.rb:19

realize too that using a prototype for a Config class is but a tiny  
tiny sample of where it might benefit someone. anywhere you have a  
singleton or a copy constructor it’s worth considering.

i’ll have some magnetic code posted soon - you can look at that for  
an example of grittier prototype use.

kind regards.

-a

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 11:54pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/8 "2007-06-05T23:54:22Z")

</div>

> of all (which becames “object’s prototype processes all unknown  
> signals”,  
> “object’s prototype can be changed” and even Io’s “prototype  
> defines lexical  
> scope”).
> 
> It seems prototype.rb now does something like “my first  
> impression”, not  
> “prototype-based entirely”.
> 
> Am I wrong?

on second thought it’s a hybrid. in prototype.rb’s case you merely  
have to consider each object’s class as it’s ‘prototype’ - all  
methods are defined/intercepted there. this a symptom of the fact  
that ruby only allows method definitions to reside in modules.

-a

---

<div class="post-metadata">

**Author:** ![ara.t.howard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a8b319/32.png) [@ara.t.howard](https://www.ruby-forum.com/u/ara.t.howard)\
**Post date:** [June 5, 2007, 11:56pm UTC](https://www.ruby-forum.com/t/prototype-2-0-0/105975/9 "2007-06-05T23:56:22Z")

</div>

From: ara.t.howard [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]  
Sent: Wednesday, June 06, 2007 12:49 AM

> > b.my\_new\_method #will b have ALL the methods of it’s prototype?
> 
> the first impl did indeed to that. the latest does not. i found it  
> flew in the face of ‘normal’ ruby design patterns - which is where  
> i’m using it after all! 😉

OK, that’s why I’ve asked about library usage.

Io (prototype-only) looks cool, when you reading tutorials, guides and  
examples. But I’m wondering, where “prototype-also” language (Ruby +  
prototype.rb) can be more effective than “prototype-neither” (Ruby  
without  
prototype.rb). It’s completely possible that advanced  
prototype-orientation  
(dynamic prototype changing and prototype-based lexical scopes) would  
have  
no use in Ruby.

V.
