prototype 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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