Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Ruby Programming Language

prototype-2.0.0


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

enjoy

-a
--
we can deny everything, except that we have the possibility of being  
better. simply reflect on that.
h.h. the 14th dalai lama

From: ara.t.howard [mailto:ara.t.how@gmail.com]
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.

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

> From: ara.t.howard [mailto:ara.t.how@gmail.com]
> 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")

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

> * 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

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
--
we can deny everything, except that we have the possibility of being  
better. simply reflect on that.
h.h. the 14th dalai lama

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

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 Gray II

From: ara.t.howard [mailto:ara.t.how@gmail.com]
Sent: Tuesday, June 05, 2007 11:03 PM

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.

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

yes, i think so:

cfp:~ > cat a.rb
require 'rubygems'
require 'prototype'
require 'ostruct'
require 'yaml'

hash = {
:id => 42,
:send => 'ara.t.how@gmail.com',
: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
"ara.t.how@gmail.com"
"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
--
we can deny everything, except that we have the possibility of being  
better. simply reflect on that.
h.h. the 14th dalai lama

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

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!

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

kind regards.

-a
--
we can deny everything, except that we have the possibility of being  
better. simply reflect on that.
h.h. the 14th dalai lama

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
--
we can deny everything, except that we have the possibility of being  
better. simply reflect on that.
h.h. the 14th dalai lama

From: ara.t.howard [mailto:ara.t.how@gmail.com]
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.

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc