Prototype design pattern

anyone know of a good impl for ruby?

regards.

-a

···

--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

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

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

ara.t.howard@noaa.gov schrieb:

···

anyone know of a good impl for ruby?

regards.

-a

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 Thu, 13 Jul 2006, Pete wrote:

Can't imagine how it could be simpler...

class SomeUselessClass
attr_accessor :a, :b, :c
def initialize
@a, @b, @c = 1, 2, 3
end

prototype = SomeUselessClass.new
prototype.a = 7

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

cheers
peter

--
suffering increases your inner strength. also, the wishing for suffering
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

···

On 7/12/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

On Thu, 13 Jul 2006, Pete wrote:

> Can't imagine how it could be simpler...
>
> class SomeUselessClass
> attr_accessor :a, :b, :c
> def initialize
> @a, @b, @c = 1, 2, 3
> end
>
> prototype = SomeUselessClass.new
> 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
--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama

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

···

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).

--
suffering increases your inner strength. also, the wishing for suffering
makes the suffering disappear.
- h.h. the 14th dali lama