Prototype design pattern

anyone know of a good impl for ruby?

regards.

-a

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’]

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! :wink:

-a

On 7/12/06, [email protected] [email protected] 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

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

[email protected] schrieb:

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