prototype 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,14 +1,14 @@
1
1
  NAME
2
-
3
2
  prototype.rb
4
3
 
5
- URIS
4
+ INSTALL
5
+ gem install prototype
6
6
 
7
- http://codeforpeople.com/lib/ruby/
7
+ URIS
8
8
  http://rubyforge.org/projects/codeforpeople/
9
+ http://codeforpeople.com/lib/ruby/
9
10
 
10
11
  SYNOPSIS
11
-
12
12
  prototype.rb facilitates a prototype based coding style
13
13
 
14
14
  http://en.wikipedia.org/wiki/Prototype-based_programming
@@ -16,13 +16,22 @@ SYNOPSIS
16
16
  for ruby
17
17
 
18
18
  WHY
19
-
20
19
  prototype based programming looks very nice ;-)
21
20
 
22
21
  also, there are many problems that a genuine singleton object with cloning
23
22
  abilities can illuminate clearly
24
23
 
24
+ it's the basis of a new rendering model for rails
25
+
25
26
  HISTORY
27
+ 2.0.0
28
+ completely gutted the prototype library and re-implemented with a
29
+ module/singleton_class/include approach.
30
+
31
+ note that this version increases a major number because it is NOT
32
+ compatible with past releases. the incompatible change is that 'clone'
33
+ now returns an object that does not reflect changes made to the parent: it
34
+ is completely independant.
26
35
 
27
36
  1.0.0
28
37
 
@@ -43,7 +52,7 @@ SAMPLES
43
52
  def answer() @a + @b end
44
53
  }
45
54
 
46
- p singleton.answer
55
+ p singleton.answer #=> 42
47
56
 
48
57
  ~ > ruby samples/a.rb
49
58
 
@@ -65,16 +74,14 @@ SAMPLES
65
74
  def connect() p [host, port] end
66
75
  }
67
76
 
68
- p DB
69
- p DB.host
70
- p DB.port
71
- p DB.conn_string
77
+ p DB.host #=> "localhost"
78
+ p DB.port #=> 4242
79
+ p DB.conn_string #=> "localhost:4242"
72
80
 
73
- DB.connect
81
+ DB.connect #=> ["locahost", 4242]
74
82
 
75
83
  ~ > ruby samples/b.rb
76
84
 
77
- #<#<Class:0x10f8948>:0x10f7fac @port=4242, @host="localhost", @conn_string="localhost:4242">
78
85
  "localhost"
79
86
  4242
80
87
  "localhost:4242"
@@ -93,32 +100,31 @@ SAMPLES
93
100
 
94
101
  b = a.clone
95
102
 
96
- p a.method
97
- p b.method
103
+ p a.method #=> 42
104
+ p b.method #=> 42
98
105
 
99
106
  a.extend{
100
107
  def method2() '42' end
101
108
  }
102
109
 
103
- p a.method2
104
- p b.method2
110
+ p a.respond_to?(:method2) #=> true
111
+ p b.respond_to?(:method2) #=> false
105
112
 
106
113
  b.extend{
107
114
  def method3() 42.0 end
108
115
  }
109
116
 
110
- p b.method3
111
- p a.method3 # throws error!
112
-
117
+ p a.respond_to?(:method3) #=> false
118
+ p b.respond_to?(:method3) #=> true
113
119
 
114
120
  ~ > ruby samples/c.rb
115
121
 
116
122
  42
117
123
  42
118
- "42"
119
- "42"
120
- 42.0
121
- samples/c.rb:24: undefined method `method3' for #<#<Class:0x10fb79c>:0x10fb42c> (NoMethodError)
124
+ true
125
+ false
126
+ false
127
+ true
122
128
 
123
129
 
124
130
  <========< samples/d.rb >========>
@@ -130,13 +136,13 @@ SAMPLES
130
136
  proto = prototype{ attributes 'a' => 1, 'b' => 2, 'c' => 3 }
131
137
  proto = prototype{ a 1; b 2; c 3 }
132
138
 
133
- %w( a b c ).each{|attr| p proto.send(attr)}
139
+ %w( a b c ).each{|attr| p proto.send(attr)} #=> 1, 2, 3
134
140
 
135
141
  clone = proto.clone
136
142
  proto.c = 42
137
143
 
138
- %w( a b c ).each{|attr| p proto.send(attr)}
139
- %w( a b c ).each{|attr| p clone.send(attr)}
144
+ %w( a b c ).each{|attr| p proto.send(attr)} #=> 1, 2, 42
145
+ %w( a b c ).each{|attr| p clone.send(attr)} #=> 1, 2, 3
140
146
 
141
147
  ~ > ruby samples/d.rb
142
148
 
@@ -162,7 +168,7 @@ SAMPLES
162
168
  @b = 2
163
169
  }
164
170
 
165
- p(proto.a + proto.b)
171
+ p(proto.a + proto.b) #=> 42
166
172
 
167
173
  ~ > ruby samples/e.rb
168
174
 
@@ -181,7 +187,7 @@ SAMPLES
181
187
 
182
188
  c = Object.prototype{ @a = 4; @b = 10; @c = 2 }
183
189
 
184
- [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) }
190
+ [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) } #=> 42, 42, 42
185
191
 
186
192
  ~ > ruby samples/f.rb
187
193
 
@@ -194,17 +200,15 @@ SAMPLES
194
200
 
195
201
  ~ > cat samples/g.rb
196
202
 
197
-
198
203
  require 'prototype'
199
204
 
200
- a = prototype
201
-
202
- b = prototype(a){ @a, @b, @c = 4, 10, 2 }
205
+ a = prototype{ @a, @b, @c = 4, 10, 2 }
203
206
 
204
- a.extend{ def answer() a * b + c end }
207
+ b = a.clone
205
208
 
206
- p b.answer
209
+ b.extend{ def answer() a * b + c end }
207
210
 
211
+ p b.answer #=> 42
208
212
 
209
213
  ~ > ruby samples/g.rb
210
214
 
@@ -225,7 +229,7 @@ SAMPLES
225
229
  sum { a + b + c }
226
230
  }
227
231
 
228
- p proto.sum
232
+ p proto.sum #=> 42
229
233
 
230
234
  ~ > ruby samples/h.rb
231
235
 
@@ -1,14 +1,14 @@
1
1
  NAME
2
-
3
2
  prototype.rb
4
3
 
5
- URIS
4
+ INSTALL
5
+ gem install prototype
6
6
 
7
- http://codeforpeople.com/lib/ruby/
7
+ URIS
8
8
  http://rubyforge.org/projects/codeforpeople/
9
+ http://codeforpeople.com/lib/ruby/
9
10
 
10
11
  SYNOPSIS
11
-
12
12
  prototype.rb facilitates a prototype based coding style
13
13
 
14
14
  http://en.wikipedia.org/wiki/Prototype-based_programming
@@ -16,13 +16,22 @@ SYNOPSIS
16
16
  for ruby
17
17
 
18
18
  WHY
19
-
20
19
  prototype based programming looks very nice ;-)
21
20
 
22
21
  also, there are many problems that a genuine singleton object with cloning
23
22
  abilities can illuminate clearly
24
23
 
24
+ it's the basis of a new rendering model for rails
25
+
25
26
  HISTORY
27
+ 2.0.0
28
+ completely gutted the prototype library and re-implemented with a
29
+ module/singleton_class/include approach.
30
+
31
+ note that this version increases a major number because it is NOT
32
+ compatible with past releases. the incompatible change is that 'clone'
33
+ now returns an object that does not reflect changes made to the parent: it
34
+ is completely independant.
26
35
 
27
36
  1.0.0
28
37
 
@@ -30,5 +39,4 @@ HISTORY
30
39
  were silently ignored
31
40
 
32
41
  SAMPLES
33
-
34
42
  @samples
data/gemspec.rb CHANGED
@@ -16,9 +16,9 @@ Gem::Specification::new do |spec|
16
16
 
17
17
  spec.has_rdoc = File::exist? "doc"
18
18
  spec.test_suite_file = "test/#{ lib }.rb" if File::directory? "test"
19
- spec.add_dependency 'attributes', '~> 3.0'
19
+ spec.add_dependency 'attributes', '>= 3.3'
20
20
 
21
21
  spec.author = "Ara T. Howard"
22
- spec.email = "ara.t.howard@noaa.gov"
22
+ spec.email = "ara.t.howard@gmail.com"
23
23
  spec.homepage = "http://codeforpeople.com/lib/ruby/#{ lib }/"
24
24
  end
@@ -0,0 +1,213 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue LoadError
4
+ nil
5
+ end
6
+
7
+ begin
8
+ require 'attributes'
9
+ rescue LoadError
10
+ warn <<-msg
11
+ attributes.rb not found!
12
+
13
+ download from:
14
+ - http://rubyforge.org/projects/codeforpeople/
15
+ - http://codeforpeople.com/lib/ruby/
16
+ msg
17
+ raise
18
+ end
19
+
20
+ #
21
+ # http://en.wikipedia.org/wiki/Prototype-based_programming
22
+ #
23
+
24
+ class Prototype
25
+ VERSION = '2.0.0'
26
+
27
+ module ClassMethods
28
+ def version() VERSION end
29
+
30
+ def inherit c = Object, *a, &b
31
+ c = c.class unless Class === c
32
+ c = Class.new c
33
+ new c, *a, &b
34
+ end
35
+ alias_method "exnihilo", "inherit"
36
+ alias_method "ex_nihilo", "inherit"
37
+
38
+ def new c = Object, *a, &b
39
+ c = c.class unless Class === c
40
+ obj = c.new *a
41
+ prototyping obj, &b
42
+ obj
43
+ end
44
+
45
+ def clone src, *a, &b
46
+ c = src.class
47
+ c = Class.new c
48
+ dst = c.new *a
49
+
50
+ sc =
51
+ class << src
52
+ self
53
+ end
54
+
55
+ modules = sc.instance_variable_get('@modules') || []
56
+ modules.each{|mod| extend dst, mod}
57
+
58
+ src.instance_variables.each do |ivar|
59
+ value = src.instance_variable_get ivar
60
+ dst.instance_variable_set ivar, value
61
+ end
62
+ prototyping dst, &b
63
+ dst
64
+ end
65
+
66
+ def prototyping obj, &b
67
+ obj.extend InstanceMethods
68
+ mod = Prototype.context &b
69
+ ivars = mod.__method__["instance_variables"].call()
70
+ ivars.each do |ivar|
71
+ value = mod.__method__["instance_variable_get"].call(ivar)
72
+ obj.instance_eval{ instance_variable_set ivar, value }
73
+ end
74
+ extend obj, mod
75
+ obj
76
+ end
77
+
78
+ def extend obj, mod
79
+ sc =
80
+ class << obj
81
+ self
82
+ end
83
+ sc.module_eval do
84
+ (@modules ||= []) << mod
85
+ include mod
86
+ end
87
+ end
88
+
89
+ def prototyped? obj
90
+ sc =
91
+ class << obj
92
+ self
93
+ end
94
+ sc.module_eval do
95
+ defined?(@prototyped) and @prototyped
96
+ end
97
+ end
98
+
99
+ def prototyped! obj
100
+ sc =
101
+ class << obj
102
+ self
103
+ end
104
+ sc.module_eval do
105
+ @prototyped = true
106
+ end
107
+ end
108
+
109
+ def context &b
110
+ mod = Module.new
111
+ sc =
112
+ class << mod
113
+ self
114
+ end
115
+
116
+ sc.module_eval do
117
+ __method__ = {} and define_method(:__method__){ __method__ }
118
+
119
+ def __call__(m, *a, &b)
120
+ meth = __method__[m.to_s]
121
+ raise NoMethodError, m.to_s unless meth
122
+ meth.call *a, &b
123
+ end
124
+
125
+ alias_method '__define_method__', 'define_method'
126
+ end
127
+
128
+ mod.methods.each{|m| mod.__method__[m] = mod.method(m) unless %w( __call__ __method__ ).include?(m)}
129
+
130
+ mod.methods.each do |m|
131
+ unless m =~ /^__|attribute/
132
+ sc.module_eval{ undef_method m }
133
+ end
134
+ end
135
+
136
+ sc.module_eval do
137
+ def method_missing m, *a, &b
138
+ if b
139
+ __define_method__ m, *a, &b
140
+ else
141
+ ivar = "@#{ m }"
142
+ case a.size
143
+ when 0
144
+ if eval("defined? #{ ivar }")
145
+ __call__ 'instance_variable_get', ivar
146
+ else
147
+ super
148
+ end
149
+ when 1
150
+ value = a.shift
151
+ __call__ 'instance_variable_set', ivar, value
152
+ else
153
+ super
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ mod.__call__ 'module_eval', &b if b
160
+
161
+ mod.__call__ 'module_eval' do
162
+ defined = __call('instance_methods').inject({}){|h,m| h.update m => true}
163
+
164
+ __call__('instance_variables').each do |ivar|
165
+ m = ivar[1..-1]
166
+ getter, setter, query = defined["#{ m }"], defined["#{ m }="], defined["#{ m }?"]
167
+
168
+ if getter.nil? and setter.nil? and query.nil?
169
+ __call__ 'attribute', m
170
+ next
171
+ end
172
+ if getter.nil?
173
+ __call__ 'module_eval', "def #{ m }() #{ ivar } end"
174
+ end
175
+ if setter.nil?
176
+ __call__ 'module_eval', "def #{ m }=(v) #{ ivar }=v end"
177
+ end
178
+ if query.nil?
179
+ __call__ 'module_eval', "def #{ m }?() defined?(#{ ivar }) and #{ ivar } end"
180
+ end
181
+ end
182
+ end
183
+
184
+ mod
185
+ end
186
+ end
187
+ extend ClassMethods
188
+
189
+ module InstanceMethods
190
+ def clone *a, &b
191
+ Prototype.clone self, *a, &b
192
+ end
193
+ def dup *a, &b
194
+ Prototype.clone self, *a, &b
195
+ end
196
+ def extend m=nil, &block
197
+ if block
198
+ prototyping(self, &block)
199
+ else
200
+ super(m)
201
+ end
202
+ self
203
+ end
204
+ end
205
+ include InstanceMethods
206
+ end
207
+
208
+ class Object
209
+ def Prototype(*a, &b) Prototype.inherit *a, &b end
210
+ def prototype(*a, &b) Prototype.inherit *a, &b end
211
+ def Prototyping(obj=nil, &b) Prototype.prototyping obj||self, &b end
212
+ def prototyping(obj=nil, &b) Prototype.prototyping obj||self, &b end
213
+ end
@@ -1,4 +1,3 @@
1
-
2
1
  begin
3
2
  require 'rubygems'
4
3
  rescue LoadError
@@ -11,11 +10,8 @@ rescue LoadError
11
10
  warn <<-msg
12
11
  attributes.rb not found!
13
12
 
14
- download from
13
+ download from:
15
14
  - http://rubyforge.org/projects/codeforpeople/
16
-
17
- or
18
-
19
15
  - http://codeforpeople.com/lib/ruby/
20
16
  msg
21
17
  raise
@@ -26,179 +22,192 @@ end
26
22
  #
27
23
 
28
24
  class Prototype
29
- VERSION = '1.0.0'
30
- def version() VERSION end
31
-
32
- module Prototypical
33
- module ClassMethods
34
- def __prototype_table__ # uses closure/init to avoid instance-var
35
- __prototype_singleton_class__{
36
- table = {}
37
- define_method('__prototype_table__'){ table }
38
- }
39
- __prototype_table__ # does not recurse!
40
- end
25
+ VERSION = '2.0.0'
41
26
 
42
- def __prototype_table_inject__ other
43
- __prototype_table__.each do |ivar, value|
44
- other.instance_variable_set ivar, value
45
- end
46
- __prototype_table__.clear
47
- end
27
+ module ClassMethods
28
+ def version() VERSION end
48
29
 
49
- def __prototype_eval__ &b
50
- tid = Thread.current.object_id.abs
51
- src, dst = "method_missing", "__method_missing_#{ tid }__"
52
- aliased = false
30
+ def inherit c = Object, *a, &b
31
+ c = c.class unless Class === c
32
+ c = Class.new c
33
+ new c, *a, &b
34
+ end
35
+ alias_method "exnihilo", "inherit"
36
+ alias_method "ex_nihilo", "inherit"
53
37
 
54
- __prototype_singleton_class__{
55
- unless respond_to? dst
56
- alias_method dst, src
57
- aliased = true
58
- end
38
+ def new c = Object, *a, &b
39
+ c = c.class unless Class === c
40
+ obj = c.new *a
41
+ prototyping obj, &b
42
+ obj
43
+ end
59
44
 
60
- def method_missing m, *a, &b
61
- __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
62
- end
45
+ def clone src, *a, &b
46
+ c = src.class
47
+ c = Class.new c
48
+ dst = c.new *a
63
49
 
64
- def __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
65
- if b
66
- define_method m, *a, &b
67
- else
68
- ivar = "@#{ m }"
69
- tid = Thread.current.object_id.abs
70
- missing = "__method_missing_#{ tid }__"
71
- if a.size == 0
72
- eval("defined? #{ ivar }") ? instance_variable_get(ivar) : method(missing).call(m, *a, &b)
73
- elsif a.size == 1
74
- instance_variable_set ivar, a.shift
75
- else
76
- method(missing).call(m, *a, &b)
77
- end
78
- end
79
- end
80
- }
50
+ sc =
51
+ class << src
52
+ self
53
+ end
81
54
 
82
- module_eval &b
55
+ modules = sc.instance_variable_get('@modules') || []
56
+ modules.each{|mod| extend dst, mod}
83
57
 
84
- ensure
85
- __prototype_singleton_class__{ alias_method src, dst } if aliased
58
+ src.instance_variables.each do |ivar|
59
+ value = src.instance_variable_get ivar
60
+ dst.instance_variable_set ivar, value
86
61
  end
62
+ prototyping dst, &b
63
+ dst
64
+ end
87
65
 
88
- def __prototype_singleton_class__ &b
89
- sc =
90
- class << self
91
- self
92
- end
93
- sc.module_eval &b if b
94
- sc
66
+ def prototyping obj, &b
67
+ obj.extend InstanceMethods
68
+ mod = Prototype.context &b
69
+ ivars = mod.__method__["instance_variables"].call()
70
+ ivars.each do |ivar|
71
+ value = mod.__method__["instance_variable_get"].call(ivar)
72
+ obj.instance_eval{ instance_variable_set ivar, value }
95
73
  end
74
+ extend obj, mod
75
+ obj
76
+ end
96
77
 
97
- def __prototype_prototype__ &b
98
- return unless b
99
-
100
- __prototype_eval__ &b
78
+ def extend obj, mod
79
+ sc =
80
+ class << obj
81
+ self
82
+ end
83
+ sc.module_eval do
84
+ (@modules ||= []) << mod
85
+ include mod
86
+ end
87
+ end
101
88
 
102
- table =
103
- instance_variables.inject({}) do |t,ivar|
104
- value =
105
- instance_eval do
106
- begin
107
- instance_variable_get ivar
108
- ensure
109
- remove_instance_variable ivar
110
- end
111
- end
112
- t.update ivar => value
113
- end
89
+ def prototyped? obj
90
+ sc =
91
+ class << obj
92
+ self
93
+ end
94
+ sc.module_eval do
95
+ defined?(@prototyped) and @prototyped
96
+ end
97
+ end
114
98
 
115
- __prototype_table__.update table
99
+ def prototyped! obj
100
+ sc =
101
+ class << obj
102
+ self
103
+ end
104
+ sc.module_eval do
105
+ @prototyped = true
116
106
  end
117
107
  end
118
108
 
119
- module InstanceMethods
120
- def initialize *a, &b
121
- __prototype_init__
122
- super
109
+ def context &b
110
+ mod = Module.new
111
+ sc =
112
+ class << mod
113
+ self
114
+ end
115
+
116
+ sc.module_eval do
117
+ __method__ = {} and define_method(:__method__){ __method__ }
118
+
119
+ def __call__(m, *a, &b)
120
+ meth = __method__[m.to_s]
121
+ raise NoMethodError, m.to_s unless meth
122
+ meth.call *a, &b
123
+ end
124
+
125
+ alias_method '__define_method__', 'define_method'
123
126
  end
124
127
 
125
- def __prototype_init__ c = self.class
126
- c.__prototype_table__.each do |ivar, value|
127
- #defined = instance_eval "defined? #{ ivar }"
128
- #unless defined
129
- instance_variable_set ivar, value
130
- #end
131
-
132
- a = ivar[%r/\w+/]
133
- defined = respond_to? a
134
- unless defined
135
- self.class.module_eval{ attribute a }
136
- end
128
+ mod.methods.each{|m| mod.__method__[m] = mod.method(m) unless %w( __call__ __method__ ).include?(m)}
129
+
130
+ mod.methods.each do |m|
131
+ unless m =~ /^__|attribute/
132
+ sc.module_eval{ undef_method m }
137
133
  end
138
134
  end
139
135
 
140
- def extend *a, &b
141
- unless a.empty?
142
- super
143
- else
144
- self.class.__prototype_prototype__ &b
145
- __prototype_init__
146
- self
136
+ sc.module_eval do
137
+ def method_missing m, *a, &b
138
+ if b
139
+ __define_method__ m, *a, &b
140
+ else
141
+ ivar = "@#{ m }"
142
+ case a.size
143
+ when 0
144
+ if eval("defined? #{ ivar }")
145
+ __call__ 'instance_variable_get', ivar
146
+ else
147
+ super
148
+ end
149
+ when 1
150
+ value = a.shift
151
+ __call__ 'instance_variable_set', ivar, value
152
+ else
153
+ super
154
+ end
155
+ end
147
156
  end
148
157
  end
149
158
 
150
- def clone *a, &b
151
- obj = prototype(self.class, *a, &b)
152
- instance_variables.each do |ivar|
153
- next if obj.instance_eval("defined? #{ ivar }")
154
- value = instance_variable_get ivar
155
- obj.instance_variable_set ivar, value
159
+ mod.__call__ 'module_eval', &b if b
160
+
161
+ mod.__call__ 'module_eval' do
162
+ defined = __call('instance_methods').inject({}){|h,m| h.update m => true}
163
+
164
+ __call__('instance_variables').each do |ivar|
165
+ m = ivar[1..-1]
166
+ getter, setter, query = defined["#{ m }"], defined["#{ m }="], defined["#{ m }?"]
167
+
168
+ if getter.nil? and setter.nil? and query.nil?
169
+ __call__ 'attribute', m
170
+ next
171
+ end
172
+ if getter.nil?
173
+ __call__ 'module_eval', "def #{ m }() #{ ivar } end"
174
+ end
175
+ if setter.nil?
176
+ __call__ 'module_eval', "def #{ m }=(v) #{ ivar }=v end"
177
+ end
178
+ if query.nil?
179
+ __call__ 'module_eval', "def #{ m }?() defined?(#{ ivar }) and #{ ivar } end"
180
+ end
156
181
  end
157
- obj
158
182
  end
159
- end
160
183
 
161
- def self.extend_object c
162
- c.extend ClassMethods
163
- c.module_eval{ include InstanceMethods }
164
- super
184
+ mod
165
185
  end
166
186
  end
187
+ extend ClassMethods
167
188
 
168
- class << self
169
- def new parent = Object, *a, &b
170
- parent = parent.class unless Class === parent
171
- c = Class.new parent
172
- c.extend Prototypical
173
- c.__prototype_table__.update parent.__prototype_table__ if
174
- parent.respond_to? '__prototype_table__'
175
- c.__prototype_prototype__ &b
176
- obj = c.new *a
177
- obj
189
+ module InstanceMethods
190
+ def clone *a, &b
191
+ Prototype.clone self, *a, &b
178
192
  end
179
-
180
- alias_method "exnihilo", "new"
181
- alias_method "ex_nihilo", "new"
182
-
183
- def prototyping obj, *a, &b
184
- c =
185
- class << obj
186
- self
187
- end
188
- parent = c.class
189
- c.extend Prototypical unless Prototypical === c
190
- c.__prototype_table__.update parent.__prototype_table__ if
191
- parent.respond_to? '__prototype_table__'
192
- c.__prototype_prototype__ &b
193
- obj.__prototype_init__ c
194
- obj
193
+ def dup *a, &b
194
+ Prototype.clone self, *a, &b
195
+ end
196
+ def extend m=nil, &block
197
+ if block
198
+ prototyping(self, &block)
199
+ else
200
+ super(m)
201
+ end
202
+ self
195
203
  end
196
204
  end
205
+ include InstanceMethods
197
206
  end
198
207
 
199
208
  class Object
200
- def Prototype(*a, &b) Prototype.new *a, &b end
201
- def prototype(*a, &b) Prototype.new *a, &b end
202
- def Prototyping(*a, &b) Prototype.prototyping self, *a, &b end
203
- def prototyping(*a, &b) Prototype.prototyping self, *a, &b end
209
+ def Prototype(*a, &b) Prototype.inherit *a, &b end
210
+ def prototype(*a, &b) Prototype.inherit *a, &b end
211
+ def Prototyping(obj=nil, &b) Prototype.prototyping obj||self, &b end
212
+ def prototyping(obj=nil, &b) Prototype.prototyping obj||self, &b end
204
213
  end
@@ -6,4 +6,4 @@ singleton = Prototype.new{
6
6
  def answer() @a + @b end
7
7
  }
8
8
 
9
- p singleton.answer
9
+ p singleton.answer #=> 42
@@ -9,9 +9,8 @@ DB = Prototype.new{
9
9
  def connect() p [host, port] end
10
10
  }
11
11
 
12
- p DB
13
- p DB.host
14
- p DB.port
15
- p DB.conn_string
12
+ p DB.host #=> "localhost"
13
+ p DB.port #=> 4242
14
+ p DB.conn_string #=> "localhost:4242"
16
15
 
17
- DB.connect
16
+ DB.connect #=> ["locahost", 4242]
@@ -6,20 +6,19 @@ a = Prototype.new{
6
6
 
7
7
  b = a.clone
8
8
 
9
- p a.method
10
- p b.method
9
+ p a.method #=> 42
10
+ p b.method #=> 42
11
11
 
12
12
  a.extend{
13
13
  def method2() '42' end
14
14
  }
15
15
 
16
- p a.method2
17
- p b.method2
16
+ p a.respond_to?(:method2) #=> true
17
+ p b.respond_to?(:method2) #=> false
18
18
 
19
19
  b.extend{
20
20
  def method3() 42.0 end
21
21
  }
22
22
 
23
- p b.method3
24
- p a.method3 # throws error!
25
-
23
+ p a.respond_to?(:method3) #=> false
24
+ p b.respond_to?(:method3) #=> true
@@ -3,10 +3,10 @@ require 'prototype'
3
3
  proto = prototype{ attributes 'a' => 1, 'b' => 2, 'c' => 3 }
4
4
  proto = prototype{ a 1; b 2; c 3 }
5
5
 
6
- %w( a b c ).each{|attr| p proto.send(attr)}
6
+ %w( a b c ).each{|attr| p proto.send(attr)} #=> 1, 2, 3
7
7
 
8
8
  clone = proto.clone
9
9
  proto.c = 42
10
10
 
11
- %w( a b c ).each{|attr| p proto.send(attr)}
12
- %w( a b c ).each{|attr| p clone.send(attr)}
11
+ %w( a b c ).each{|attr| p proto.send(attr)} #=> 1, 2, 42
12
+ %w( a b c ).each{|attr| p clone.send(attr)} #=> 1, 2, 3
@@ -5,4 +5,4 @@ proto = Object.prototype{
5
5
  @b = 2
6
6
  }
7
7
 
8
- p(proto.a + proto.b)
8
+ p(proto.a + proto.b) #=> 42
@@ -6,4 +6,4 @@ b = Object.prototype{ a 4; b 10; c 2 }
6
6
 
7
7
  c = Object.prototype{ @a = 4; @b = 10; @c = 2 }
8
8
 
9
- [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) }
9
+ [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) } #=> 42, 42, 42
@@ -1,11 +1,9 @@
1
-
2
1
  require 'prototype'
3
2
 
4
- a = prototype
5
-
6
- b = prototype(a){ @a, @b, @c = 4, 10, 2 }
3
+ a = prototype{ @a, @b, @c = 4, 10, 2 }
7
4
 
8
- a.extend{ def answer() a * b + c end }
5
+ b = a.clone
9
6
 
10
- p b.answer
7
+ b.extend{ def answer() a * b + c end }
11
8
 
9
+ p b.answer #=> 42
@@ -8,4 +8,4 @@ proto = prototype{
8
8
  sum { a + b + c }
9
9
  }
10
10
 
11
- p proto.sum
11
+ p proto.sum #=> 42
metadata CHANGED
@@ -3,12 +3,12 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: prototype
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2007-05-24 00:00:00 -06:00
6
+ version: 2.0.0
7
+ date: 2007-06-04 00:00:00 -06:00
8
8
  summary: prototype
9
9
  require_paths:
10
10
  - lib
11
- email: ara.t.howard@noaa.gov
11
+ email: ara.t.howard@gmail.com
12
12
  homepage: http://codeforpeople.com/lib/ruby/prototype/
13
13
  rubyforge_project:
14
14
  description:
@@ -29,14 +29,13 @@ post_install_message:
29
29
  authors:
30
30
  - Ara T. Howard
31
31
  files:
32
- - a.rb
33
32
  - gemspec.rb
34
33
  - gen_readme.rb
35
34
  - install.rb
36
35
  - lib
37
- - lib/prototype-1.0.0.rb
36
+ - lib/prototype-2.0.0.rb
38
37
  - lib/prototype.rb
39
- - prototype-1.0.0.gem
38
+ - prototype-2.0.0.gem
40
39
  - README
41
40
  - README.tmpl
42
41
  - samples
@@ -67,7 +66,7 @@ dependencies:
67
66
  version_requirement:
68
67
  version_requirements: !ruby/object:Gem::Version::Requirement
69
68
  requirements:
70
- - - ~>
69
+ - - ">="
71
70
  - !ruby/object:Gem::Version
72
- version: "3.0"
71
+ version: "3.3"
73
72
  version:
data/a.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'prototype'
2
-
3
- a = prototype{ a 42 }
4
- b = a.clone{ a 42.0 }
5
-
6
- p a.a
7
- p b.a
@@ -1,204 +0,0 @@
1
-
2
- begin
3
- require 'rubygems'
4
- rescue LoadError
5
- nil
6
- end
7
-
8
- begin
9
- require 'attributes'
10
- rescue LoadError
11
- warn <<-msg
12
- attributes.rb not found!
13
-
14
- download from
15
- - http://rubyforge.org/projects/codeforpeople/
16
-
17
- or
18
-
19
- - http://codeforpeople.com/lib/ruby/
20
- msg
21
- raise
22
- end
23
-
24
- #
25
- # http://en.wikipedia.org/wiki/Prototype-based_programming
26
- #
27
-
28
- class Prototype
29
- VERSION = '1.0.0'
30
- def version() VERSION end
31
-
32
- module Prototypical
33
- module ClassMethods
34
- def __prototype_table__ # uses closure/init to avoid instance-var
35
- __prototype_singleton_class__{
36
- table = {}
37
- define_method('__prototype_table__'){ table }
38
- }
39
- __prototype_table__ # does not recurse!
40
- end
41
-
42
- def __prototype_table_inject__ other
43
- __prototype_table__.each do |ivar, value|
44
- other.instance_variable_set ivar, value
45
- end
46
- __prototype_table__.clear
47
- end
48
-
49
- def __prototype_eval__ &b
50
- tid = Thread.current.object_id.abs
51
- src, dst = "method_missing", "__method_missing_#{ tid }__"
52
- aliased = false
53
-
54
- __prototype_singleton_class__{
55
- unless respond_to? dst
56
- alias_method dst, src
57
- aliased = true
58
- end
59
-
60
- def method_missing m, *a, &b
61
- __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
62
- end
63
-
64
- def __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
65
- if b
66
- define_method m, *a, &b
67
- else
68
- ivar = "@#{ m }"
69
- tid = Thread.current.object_id.abs
70
- missing = "__method_missing_#{ tid }__"
71
- if a.size == 0
72
- eval("defined? #{ ivar }") ? instance_variable_get(ivar) : method(missing).call(m, *a, &b)
73
- elsif a.size == 1
74
- instance_variable_set ivar, a.shift
75
- else
76
- method(missing).call(m, *a, &b)
77
- end
78
- end
79
- end
80
- }
81
-
82
- module_eval &b
83
-
84
- ensure
85
- __prototype_singleton_class__{ alias_method src, dst } if aliased
86
- end
87
-
88
- def __prototype_singleton_class__ &b
89
- sc =
90
- class << self
91
- self
92
- end
93
- sc.module_eval &b if b
94
- sc
95
- end
96
-
97
- def __prototype_prototype__ &b
98
- return unless b
99
-
100
- __prototype_eval__ &b
101
-
102
- table =
103
- instance_variables.inject({}) do |t,ivar|
104
- value =
105
- instance_eval do
106
- begin
107
- instance_variable_get ivar
108
- ensure
109
- remove_instance_variable ivar
110
- end
111
- end
112
- t.update ivar => value
113
- end
114
-
115
- __prototype_table__.update table
116
- end
117
- end
118
-
119
- module InstanceMethods
120
- def initialize *a, &b
121
- __prototype_init__
122
- super
123
- end
124
-
125
- def __prototype_init__ c = self.class
126
- c.__prototype_table__.each do |ivar, value|
127
- #defined = instance_eval "defined? #{ ivar }"
128
- #unless defined
129
- instance_variable_set ivar, value
130
- #end
131
-
132
- a = ivar[%r/\w+/]
133
- defined = respond_to? a
134
- unless defined
135
- self.class.module_eval{ attribute a }
136
- end
137
- end
138
- end
139
-
140
- def extend *a, &b
141
- unless a.empty?
142
- super
143
- else
144
- self.class.__prototype_prototype__ &b
145
- __prototype_init__
146
- self
147
- end
148
- end
149
-
150
- def clone *a, &b
151
- obj = prototype(self.class, *a, &b)
152
- instance_variables.each do |ivar|
153
- next if obj.instance_eval("defined? #{ ivar }")
154
- value = instance_variable_get ivar
155
- obj.instance_variable_set ivar, value
156
- end
157
- obj
158
- end
159
- end
160
-
161
- def self.extend_object c
162
- c.extend ClassMethods
163
- c.module_eval{ include InstanceMethods }
164
- super
165
- end
166
- end
167
-
168
- class << self
169
- def new parent = Object, *a, &b
170
- parent = parent.class unless Class === parent
171
- c = Class.new parent
172
- c.extend Prototypical
173
- c.__prototype_table__.update parent.__prototype_table__ if
174
- parent.respond_to? '__prototype_table__'
175
- c.__prototype_prototype__ &b
176
- obj = c.new *a
177
- obj
178
- end
179
-
180
- alias_method "exnihilo", "new"
181
- alias_method "ex_nihilo", "new"
182
-
183
- def prototyping obj, *a, &b
184
- c =
185
- class << obj
186
- self
187
- end
188
- parent = c.class
189
- c.extend Prototypical unless Prototypical === c
190
- c.__prototype_table__.update parent.__prototype_table__ if
191
- parent.respond_to? '__prototype_table__'
192
- c.__prototype_prototype__ &b
193
- obj.__prototype_init__ c
194
- obj
195
- end
196
- end
197
- end
198
-
199
- class Object
200
- def Prototype(*a, &b) Prototype.new *a, &b end
201
- def prototype(*a, &b) Prototype.new *a, &b end
202
- def Prototyping(*a, &b) Prototype.prototyping self, *a, &b end
203
- def prototyping(*a, &b) Prototype.prototyping self, *a, &b end
204
- end