# Prototype design pattern

**URL:** <https://www.ruby-forum.com/t/prototype-design-pattern/98105>\
**Category:** Ruby\
**Created:** [July 12, 2006, 4:30pm UTC](https://www.ruby-forum.com/t/prototype-design-pattern/98105 "2006-07-12T16:30:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 12, 2006, 4:30pm UTC](https://www.ruby-forum.com/t/prototype-design-pattern/98105/1 "2006-07-12T16:30:00Z")

</div>

anyone know of a good impl for ruby?

regards.

-a

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 12, 2006, 4:49pm UTC](https://www.ruby-forum.com/t/prototype-design-pattern/98105/2 "2006-07-12T16:49:47Z")

</div>

What criteria for “good”? I’m not aware of any lib that preports  
“enterprise quality” or anthing like that. I’ve played with the ideas  
though. Prototype-based OOP interests me. On the surface it appears as  
simple as aliasing an Object#new to #$dup and instantiation a bunch of  
initiaial prototypes for each class – of course some classes won’t  
play nice woth this, like File for instance.

Other than that I also played around with this:

module ProtobaseKernel

def meta ; (class \<\< self; self; end) ; end

def obj(&blk)  
o = Object.new  
o.instance\_eval(&blk)  
h = {}  
iv = o.instance\_variables  
iv.each { |k| h[k[1…-1].to\_sym] = o.instance\_eval{  
instance\_variable\_get(k) } }  
o.meta.class\_eval {  
h.each { |k,v|  
case v  
when Proc  
#define\_method(k){ |\*args| v[\*args] }  
attr\_reader k  
else  
attr\_accessor k  
end  
}  
}  
o  
end

def fn(&blk)  
proc(&blk)  
end

def new(o=nil)  
return o.clone if o  
return self.clone  
end

end

class Object  
include ProtobaseKernel  
end

# Example -----------------

person = obj {  
@name = ‘’  
@age = 0  
@announce = fn { |x| “#{x}, #{name} is #{age}” }  
}

person.name = ‘Tom’  
person.age = 35  
puts person.announce[‘Peter’]

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 13, 2006, 1:01am UTC](https://www.ruby-forum.com/t/prototype-design-pattern/98105/3 "2006-07-13T01:01:06Z")

</div>

On Thu, 13 Jul 2006, Pete wrote:

> prototype.a = 7
> 
> // create instances from prototype  
> o1 = prototype.clone  
> o2 = prototype.clone  
> o3 = prototype.clone
> 
> cheers  
> peter

mostly succinctness, but also semantics. cloning a prototype should not  
copy  
it’s instance variables, but rather stamp out a new instance - sort of  
like a  
constructor. here’s a snippet from my latest branch:

```
 jib:~/eg/ruby/prototype/prototype-0.1.0 > cat samples/d.rb
 require 'prototype'

 proto = prototype{ attributes 'a' => 1, 'b' => 2, 'c' => 3 }

 %w( a b c ).each{|attr| p proto.send(attr)}

 clone = proto.clone
 proto.c = 42

 %w( a b c ).each{|attr| p proto.send(attr)}
 %w( a b c ).each{|attr| p clone.send(attr)}

 jib:~/eg/ruby/prototype/prototype-0.1.0 > ruby -Ilib samples/d.rb
 1
 2
 3
 1
 2
 42
 1
 2
 3

```

note that this

```
 proto = Prototype{ attributes 'a' => 1, 'b' => 2, 'c' => 3 }

```

or, even shorter

```
 proto = Prototype{ a 1; b 2; c 3 }

```

are the same, but more, than this

class SomeUselessClass  
attr\_accessor :a, :b, :c  
def initialize  
@a, @b, @c = 1, 2, 3  
end  
end  
prototype = SomeUselessClass.new

actually - to have the literal equiv your code would need to be closer  
to

class SomeUselessClass  
ATTRIBUTES = %w( a b c)

```
 ATTRIBUTES.each do |a|
   attr_accessor a
   alias_method "#{ a }?", "#{ a }"
 end

 def self.attributes() ATTRIBUTES end

 def initialize
   @a, @b, @c = 1, 2, 3
 end

```

end

prototype = SomeUselessClass.new

and actually there’s even a bit more…

and it’s not even golfing! 😉

-a

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 13, 2006, 3:48am UTC](https://www.ruby-forum.com/t/prototype-design-pattern/98105/4 "2006-07-13T03:48:05Z")

</div>

On 7/12/06, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 
> 
> ```
> %w( a b c ).each{|attr| p proto.send(attr)}
> 2
> 
> def initialize
> ATTRIBUTES.each do |a|
> 
> ```
> 
> makes the suffering disappear.
> 
> - h.h. the 14th dali lama

Gosh! Blink and I miss the fun. Ironically, I’ve been using traits +  
some sugar for something like this but your implementation is more -  
well - prototypey! Nice work (again).

Regards,  
Sean

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 12, 2006, 9:49pm UTC](https://www.ruby-forum.com/t/prototype-design-pattern/98105/5 "2006-07-12T21:49:58Z")

</div>

Can’t imagine how it could be simpler…

class SomeUselessClass  
attr\_accessor :a, :b, :c  
def initialize  
@a, @b, @c = 1, 2, 3  
end  
end

prototype = SomeUselessClass.new  
prototype.a = 7

// create instances from prototype  
o1 = prototype.clone  
o2 = prototype.clone  
o3 = prototype.clone

cheers  
peter

removed\_email\_address@domain.invalid schrieb:

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 13, 2006, 3:59pm UTC](https://www.ruby-forum.com/t/prototype-design-pattern/98105/6 "2006-07-13T15:59:22Z")

</div>

On Thu, 13 Jul 2006, Sean O’Halpin wrote:

> Gosh! Blink and I miss the fun. Ironically, I’ve been using traits + some  
> sugar for something like this but your implementation is more - well -  
> prototypey! Nice work (again).

yeah - i’ve been doing the same with traits. this one uses  
attributes.rb,  
which isn’t quite as powerful but extremely simply - it’s basically all  
the  
best ideas from the metakoans quiz rolled into a nice compact lib, which  
i’ll  
probably release later today too… anyhow, i though of using traits  
but it’s  
pretty heavyweight if you don’t need all the features.

cheers.

-a
