prototype 0.1.0 → 0.2.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
@@ -9,7 +9,7 @@ URIS
9
9
 
10
10
  SYNOPSIS
11
11
 
12
- prototype.rb implements the prototype design pattern
12
+ prototype.rb facilitates a prototype based coding style
13
13
 
14
14
  http://en.wikipedia.org/wiki/Prototype-based_programming
15
15
 
@@ -19,117 +19,205 @@ WHY
19
19
 
20
20
  prototype based programming can look very nice ;-)
21
21
 
22
- EXAMPLES
22
+ SAMPLES
23
23
 
24
- __________________________________________
25
- ~ > cat samples/a.rb
26
- __________________________________________
27
- require 'prototype'
28
-
29
- singleton = Prototype.new{
30
- @a, @b = 40, 2
24
+ <========< samples/a.rb >========>
31
25
 
32
- def answer() @a + @b end
33
- }
34
-
35
- p singleton.answer
26
+ ~ > cat samples/a.rb
36
27
 
28
+ require 'prototype'
29
+
30
+ singleton = Prototype.new{
31
+ @a, @b = 40, 2
32
+
33
+ def answer() @a + @b end
34
+ }
35
+
36
+ p singleton.answer
37
37
 
38
- __________________________________________
39
38
  ~ > ruby samples/a.rb
40
- __________________________________________
41
- 42
42
39
 
40
+ 42
43
41
 
44
42
 
45
- __________________________________________
46
- ~ > cat samples/b.rb
47
- __________________________________________
48
- require 'prototype'
49
-
50
- DB = Prototype.new{
51
- host 'localhost'
52
- port 4242
53
-
54
- def connect() p [host, port] end
55
- }
43
+ <========< samples/b.rb >========>
56
44
 
57
- p DB
58
- p DB.host
59
- p DB.port
60
- DB.connect
45
+ ~ > cat samples/b.rb
61
46
 
47
+ require 'prototype'
48
+
49
+ DB = Prototype.new{
50
+ host 'localhost'
51
+ port 4242
52
+
53
+ conn_string [host, port].join(':')
54
+
55
+ def connect() p [host, port] end
56
+ }
57
+
58
+ p DB
59
+ p DB.host
60
+ p DB.port
61
+ p DB.conn_string
62
+
63
+ DB.connect
62
64
 
63
- __________________________________________
64
65
  ~ > ruby samples/b.rb
65
- __________________________________________
66
- "localhost"
67
- 4242
68
- ["localhost", 4242]
69
-
70
66
 
67
+ #<#<Class:0xb7595348>:0xb7595438 @conn_string="localhost:4242", @port=4242, @host="localhost">
68
+ "localhost"
69
+ 4242
70
+ "localhost:4242"
71
+ ["localhost", 4242]
72
+
73
+
74
+ <========< samples/c.rb >========>
75
+
76
+ ~ > cat samples/c.rb
77
+
78
+ require 'prototype'
79
+
80
+ a = Prototype.new{
81
+ def method() 42 end
82
+ }
83
+
84
+ b = a.clone
85
+
86
+ p a.method
87
+ p b.method
88
+
89
+ a.extend{
90
+ def method2() '42' end
91
+ }
92
+
93
+ p a.method2
94
+ p b.method2
95
+
96
+ b.extend{
97
+ def method3() 42.0 end
98
+ }
99
+
100
+ p b.method3
101
+ p a.method3 # throws error!
102
+
103
+
104
+ ~ > ruby samples/c.rb
105
+
106
+ 42
107
+ 42
108
+ "42"
109
+ "42"
110
+ 42.0
111
+ samples/c.rb:24: undefined method `method3' for #<#<Class:0xb7595860>:0xb75953c4> (NoMethodError)
112
+
113
+
114
+ <========< samples/d.rb >========>
115
+
116
+ ~ > cat samples/d.rb
117
+
118
+ require 'prototype'
119
+
120
+ proto = prototype{ attributes 'a' => 1, 'b' => 2, 'c' => 3 }
121
+ proto = prototype{ a 1; b 2; c 3 }
122
+
123
+ %w( a b c ).each{|attr| p proto.send(attr)}
124
+
125
+ clone = proto.clone
126
+ proto.c = 42
127
+
128
+ %w( a b c ).each{|attr| p proto.send(attr)}
129
+ %w( a b c ).each{|attr| p clone.send(attr)}
130
+
131
+ ~ > ruby samples/d.rb
132
+
133
+ 1
134
+ 2
135
+ 3
136
+ 1
137
+ 2
138
+ 42
139
+ 1
140
+ 2
141
+ 3
142
+
143
+
144
+ <========< samples/e.rb >========>
71
145
 
72
- __________________________________________
73
146
  ~ > cat samples/e.rb
74
- __________________________________________
75
- require 'prototype'
76
-
77
- proto = prototype{
78
- @a = 40
79
- @b = 2
80
- }
81
147
 
82
- p(proto.a + proto.b)
148
+ require 'prototype'
149
+
150
+ proto = prototype{
151
+ @a = 40
152
+ @b = 2
153
+ }
154
+
155
+ p(proto.a + proto.b)
83
156
 
157
+ ~ > ruby samples/e.rb
84
158
 
85
- ~ > ruby -Ilib samples/e.rb
86
- 42
159
+ 42
87
160
 
88
161
 
162
+ <========< samples/f.rb >========>
89
163
 
90
- __________________________________________
91
164
  ~ > cat samples/f.rb
92
- __________________________________________
93
- require 'prototype'
94
-
95
- a = prototype{ attributes 'a' => 4, 'b' => 10, 'c' => 2 }
96
-
97
- b = prototype{ a 4; b 10; c 2 }
98
-
99
- c = prototype{ @a, @b, @c = 4, 10, 2 }
100
165
 
101
- [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) }
166
+ require 'prototype'
167
+
168
+ a = prototype{ attributes 'a' => 4, 'b' => 10, 'c' => 2}
169
+
170
+ b = prototype{ a 4; b 10; c 2 }
171
+
172
+ c = prototype{ @a = 4; @b = 10; @c = 2 }
173
+
174
+ [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) }
102
175
 
176
+ ~ > ruby samples/f.rb
103
177
 
104
- ~ > ruby -Ilib samples/f.rb
105
- 42
106
- 42
107
- 42
178
+ 42
179
+ 42
180
+ 42
108
181
 
109
182
 
183
+ <========< samples/g.rb >========>
110
184
 
111
- __________________________________________
112
185
  ~ > cat samples/g.rb
113
- __________________________________________
114
- require 'prototype'
115
186
 
116
- a = prototype
187
+
188
+ require 'prototype'
189
+
190
+ a = prototype
191
+
192
+ b = prototype(a){ @a, @b, @c = 4, 10, 2 }
193
+
194
+ a.extend{ def answer() a * b + c end }
195
+
196
+ p b.answer
197
+
117
198
 
118
- b = prototype(a){ @a, @b, @c = 4, 10, 2 }
199
+ ~ > ruby samples/g.rb
119
200
 
120
- a.extend{ def answer() a * b + c end }
201
+ 42
121
202
 
122
- p b.answer
123
203
 
204
+ <========< samples/h.rb >========>
124
205
 
125
- ~ > ruby -Ilib samples/g.rb
126
- 42
206
+ ~ > cat samples/h.rb
127
207
 
128
-
208
+ require 'prototype'
209
+
210
+ proto = prototype{
211
+ a 1
212
+ b 1
213
+ c 40
214
+
215
+ sum { a + b + c }
216
+ }
217
+
218
+ p proto.sum
129
219
 
130
- DOCS
220
+ ~ > ruby samples/h.rb
131
221
 
132
- see
222
+ 42
133
223
 
134
- lib/*rb
135
- samples/*rb
data/README.tmpl ADDED
@@ -0,0 +1,24 @@
1
+ NAME
2
+
3
+ prototype.rb
4
+
5
+ URIS
6
+
7
+ http://codeforpeople.com/lib/ruby/
8
+ http://rubyforge.org/projects/codeforpeople/
9
+
10
+ SYNOPSIS
11
+
12
+ prototype.rb facilitates a prototype based coding style
13
+
14
+ http://en.wikipedia.org/wiki/Prototype-based_programming
15
+
16
+ for ruby
17
+
18
+ WHY
19
+
20
+ prototype based programming can look very nice ;-)
21
+
22
+ SAMPLES
23
+
24
+ @samples
data/gemspec.rb CHANGED
@@ -16,6 +16,7 @@ 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
20
 
20
21
  spec.author = "Ara T. Howard"
21
22
  spec.email = "ara.t.howard@noaa.gov"
data/gen_readme.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'pathname'
2
+
3
+ $VERBOSE=nil
4
+
5
+ def indent s, n = 2
6
+ ws = ' ' * n
7
+ s.gsub %r/^/, ws
8
+ end
9
+
10
+ template = IO::read 'README.tmpl'
11
+
12
+ samples = ''
13
+ prompt = '~ > '
14
+
15
+ Dir['sample*/*'].sort.each do |sample|
16
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
17
+
18
+ cmd = "cat #{ sample }"
19
+ samples << indent(prompt + cmd, 2) << "\n\n"
20
+ samples << indent(`#{ cmd }`, 4) << "\n"
21
+
22
+ cmd = "ruby #{ sample }"
23
+ samples << indent(prompt + cmd, 2) << "\n\n"
24
+
25
+ cmd = "ruby -Ilib #{ sample }"
26
+ samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
27
+ end
28
+
29
+ #samples.gsub! %r/^/, ' '
30
+
31
+ readme = template.gsub %r/^\s*@samples\s*$/, samples
32
+ print readme
@@ -0,0 +1,177 @@
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 = '0.2.0'
30
+
31
+ module Prototypical
32
+ module ClassMethods
33
+ def __prototype_table__ # uses closure/init to avoid instance-var
34
+ __prototype_singleton_class__{
35
+ table = {}
36
+ define_method('__prototype_table__'){ table }
37
+ }
38
+ __prototype_table__
39
+ end
40
+
41
+ def __prototype_eval__ &b
42
+ tid = Thread.current.object_id.abs
43
+ src, dst = "method_missing", "__method_missing_#{ tid }__"
44
+ aliased = false
45
+
46
+ __prototype_singleton_class__{
47
+ unless respond_to? dst
48
+ alias_method dst, src
49
+ aliased = true
50
+ end
51
+
52
+ def method_missing m, *a, &b
53
+ __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
54
+ end
55
+
56
+ def __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
57
+ if b
58
+ define_method m, *a, &b
59
+ else
60
+ ivar = "@#{ m }"
61
+ if a.size == 0
62
+ defined?(ivar) ? instance_variable_get(ivar) : super
63
+ elsif a.size == 1
64
+ instance_variable_set ivar, a.shift
65
+ else
66
+ __method_missing__(m, *a, &b)
67
+ end
68
+ end
69
+ end
70
+ }
71
+
72
+ module_eval &b
73
+
74
+ ensure
75
+ __prototype_singleton_class__{ alias_method src, dst } if aliased
76
+ end
77
+
78
+ def __prototype_singleton_class__ &b
79
+ sc =
80
+ class << self
81
+ self
82
+ end
83
+ sc.module_eval &b if b
84
+ sc
85
+ end
86
+
87
+ def __prototype_prototype__ &b
88
+ return unless b
89
+
90
+ __prototype_eval__ &b
91
+
92
+ table =
93
+ instance_variables.inject({}) do |t,ivar|
94
+ value =
95
+ instance_eval do
96
+ begin
97
+ instance_variable_get ivar
98
+ ensure
99
+ remove_instance_variable ivar
100
+ end
101
+ end
102
+ t.update ivar => value
103
+ end
104
+
105
+ __prototype_table__.update table
106
+ end
107
+ end
108
+
109
+ module InstanceMethods
110
+ def initialize *a, &b
111
+ __prototype_init__
112
+ super
113
+ end
114
+
115
+ def __prototype_init__
116
+ self.class.__prototype_table__.each do |ivar, value|
117
+ defined = instance_eval "defined? #{ ivar }"
118
+ unless defined
119
+ instance_variable_set ivar, value
120
+ end
121
+
122
+ a = ivar[%r/\w+/]
123
+ defined = respond_to? a
124
+ unless defined
125
+ self.class.module_eval{ attribute a => value }
126
+ end
127
+ end
128
+ end
129
+
130
+ def extend *a, &b
131
+ unless a.empty?
132
+ super
133
+ else
134
+ self.class.__prototype_prototype__ &b
135
+ __prototype_init__
136
+ self
137
+ end
138
+ end
139
+
140
+ def clone *a, &b
141
+ obj = prototype(self.class, *a, &b)
142
+ instance_variables.each do |ivar|
143
+ value = instance_variable_get ivar
144
+ obj.instance_variable_set ivar, value
145
+ end
146
+ obj
147
+ end
148
+ end
149
+
150
+ def self.extend_object c
151
+ c.extend ClassMethods
152
+ c.module_eval{ include InstanceMethods }
153
+ super
154
+ end
155
+ end
156
+
157
+ class << self
158
+ def new parent = Object, *a, &b
159
+ parent = parent.class unless Class === parent
160
+ c = Class.new parent
161
+ c.extend Prototypical
162
+ c.__prototype_table__.update parent.__prototype_table__ if
163
+ parent.respond_to? '__prototype_table__'
164
+ c.__prototype_prototype__ &b
165
+ obj = c.new *a
166
+ obj
167
+ end
168
+
169
+ alias_method "exnihilo", "new"
170
+ alias_method "ex_nihilo", "new"
171
+ end
172
+ end
173
+
174
+ class Object
175
+ def Prototype(*a, &b) Prototype.new *a, &b end
176
+ def prototype(*a, &b) Prototype.new *a, &b end
177
+ end
data/lib/prototype.rb CHANGED
@@ -1,155 +1,155 @@
1
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
+
2
24
  #
3
25
  # http://en.wikipedia.org/wiki/Prototype-based_programming
4
26
  #
5
27
 
6
28
  class Prototype
7
- VERSION = '0.1.0'
8
-
9
- #
10
- # inline my attribute.rb file here
11
- #
12
- module Attrbiutes
13
- def attributes *a, &b
14
- unless a.empty?
15
- hashes, names = a.partition{|x| Hash === x}
16
-
17
- names_and_defaults = {}
18
- hashes.each{|h| names_and_defaults.update h}
19
- names.each{|name| names_and_defaults.update name => nil}
20
-
21
- names_and_defaults.each do |name, default|
22
- init = b || lambda { default }
23
- ivar = "@#{ name }"
24
- getter = "#{ name }"
25
- setter = "#{ name }="
26
- query = "#{ name }?"
27
-
28
- define_method(setter) do |value|
29
- instance_variable_set ivar, value
29
+ VERSION = '0.2.0'
30
+
31
+ module Prototypical
32
+ module ClassMethods
33
+ def __prototype_table__ # uses closure/init to avoid instance-var
34
+ __prototype_singleton_class__{
35
+ table = {}
36
+ define_method('__prototype_table__'){ table }
37
+ }
38
+ __prototype_table__
39
+ end
40
+
41
+ def __prototype_eval__ &b
42
+ tid = Thread.current.object_id.abs
43
+ src, dst = "method_missing", "__method_missing_#{ tid }__"
44
+ aliased = false
45
+
46
+ __prototype_singleton_class__{
47
+ unless respond_to? dst
48
+ alias_method dst, src
49
+ aliased = true
30
50
  end
31
51
 
32
- define_method(getter) do |*value|
33
- unless value.empty?
34
- send setter, value.shift
52
+ def method_missing m, *a, &b
53
+ __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
54
+ end
55
+
56
+ def __prototype_barewords_can_set_and_get_ivars_and_define_methods__ m, *a, &b
57
+ if b
58
+ define_method m, *a, &b
35
59
  else
36
- defined = instance_eval "defined? #{ ivar }"
37
- unless defined
38
- send setter, instance_eval(&init)
60
+ ivar = "@#{ m }"
61
+ if a.size == 0
62
+ defined?(ivar) ? instance_variable_get(ivar) : super
63
+ elsif a.size == 1
64
+ instance_variable_set ivar, a.shift
65
+ else
66
+ __method_missing__(m, *a, &b)
39
67
  end
40
- instance_variable_get ivar
41
68
  end
42
69
  end
70
+ }
43
71
 
44
- alias_method query, getter
72
+ module_eval &b
45
73
 
46
- (attributes << name).uniq!
47
- attributes
48
- end
49
- else
50
- @attributes ||= []
74
+ ensure
75
+ __prototype_singleton_class__{ alias_method src, dst } if aliased
51
76
  end
52
- end
53
77
 
54
- def attribute *a, &b
55
- attributes *a, &b
56
- end
57
- end
58
-
59
- module ClassMethods
60
- include Attrbiutes
61
-
62
- def method_missing m, *a, &b
63
- ivar = "@#{ m }"
64
- if a.size == 0
65
- if defined? ivar
66
- instance_variable_get ivar
67
- else
68
- super
69
- end
70
- elsif a.size == 1
71
- instance_variable_set ivar, a.shift
72
- else
73
- super
78
+ def __prototype_singleton_class__ &b
79
+ sc =
80
+ class << self
81
+ self
82
+ end
83
+ sc.module_eval &b if b
84
+ sc
74
85
  end
75
- end
76
- end
77
86
 
78
- module InstanceMethods
79
- def initialize(*a, &b)
80
- __protoinit__
81
- super
82
- end
87
+ def __prototype_prototype__ &b
88
+ return unless b
83
89
 
84
- def __protoinit__
85
- self.class.__prototable__.each do |ivar, value|
86
- defined = instance_eval "defined? #{ ivar }"
87
- unless defined
88
- instance_variable_set ivar, value
89
- end
90
+ __prototype_eval__ &b
90
91
 
91
- a = ivar[%r/\w+/]
92
- #defined = respond_to? a
93
- defined = self.class.module_eval{ attributes }.include? a
94
- unless defined
95
- self.class.module_eval{ attribute a }
96
- end
92
+ table =
93
+ instance_variables.inject({}) do |t,ivar|
94
+ value =
95
+ instance_eval do
96
+ begin
97
+ instance_variable_get ivar
98
+ ensure
99
+ remove_instance_variable ivar
100
+ end
101
+ end
102
+ t.update ivar => value
103
+ end
104
+
105
+ __prototype_table__.update table
97
106
  end
98
107
  end
99
108
 
100
- def extend *a, &b
101
- unless a.empty?
109
+ module InstanceMethods
110
+ def initialize *a, &b
111
+ __prototype_init__
102
112
  super
103
- else
104
- self.class.__prototype__ &b
105
- __protoinit__
106
- self
107
113
  end
108
- end
109
114
 
110
- def clone *a, &b
111
- obj = prototype(self.class, *a, &b)
112
- instance_variables.each do |ivar|
113
- value = instance_variable_get ivar
114
- obj.instance_variable_set ivar, value
115
- end
116
- obj
117
- end
118
- end
115
+ def __prototype_init__
116
+ self.class.__prototype_table__.each do |ivar, value|
117
+ defined = instance_eval "defined? #{ ivar }"
118
+ unless defined
119
+ instance_variable_set ivar, value
120
+ end
119
121
 
120
- module Prototype
121
- def __prototable__ # uses const to avoid copying instance var
122
- if const_defined? 'PROTOTABLE'
123
- const_get 'PROTOTABLE'
124
- else
125
- const_set 'PROTOTABLE', {}
122
+ a = ivar[%r/\w+/]
123
+ defined = respond_to? a
124
+ unless defined
125
+ self.class.module_eval{ attribute a => value }
126
+ end
127
+ end
126
128
  end
127
- end
128
-
129
- def __prototype__ &b
130
- return unless b
131
-
132
- module_eval &b
133
129
 
134
- table =
135
- instance_variables.inject({}) do |t,ivar|
136
- value =
137
- instance_eval do
138
- begin
139
- instance_variable_get ivar
140
- ensure
141
- remove_instance_variable ivar
142
- end
143
- end
144
- t.update ivar => value
130
+ def extend *a, &b
131
+ unless a.empty?
132
+ super
133
+ else
134
+ self.class.__prototype_prototype__ &b
135
+ __prototype_init__
136
+ self
145
137
  end
138
+ end
146
139
 
147
- __prototable__.update table
140
+ def clone *a, &b
141
+ obj = prototype(self.class, *a, &b)
142
+ instance_variables.each do |ivar|
143
+ value = instance_variable_get ivar
144
+ obj.instance_variable_set ivar, value
145
+ end
146
+ obj
147
+ end
148
148
  end
149
149
 
150
- def self.extend_object other
151
- other.extend ClassMethods
152
- other.module_eval{ include InstanceMethods }
150
+ def self.extend_object c
151
+ c.extend ClassMethods
152
+ c.module_eval{ include InstanceMethods }
153
153
  super
154
154
  end
155
155
  end
@@ -158,10 +158,10 @@ class Prototype
158
158
  def new parent = Object, *a, &b
159
159
  parent = parent.class unless Class === parent
160
160
  c = Class.new parent
161
- c.extend Prototype
162
- prototable = parent.const_get 'PROTOTABLE' rescue nil
163
- c.__prototable__.update prototable if prototable
164
- c.__prototype__ &b
161
+ c.extend Prototypical
162
+ c.__prototype_table__.update parent.__prototype_table__ if
163
+ parent.respond_to? '__prototype_table__'
164
+ c.__prototype_prototype__ &b
165
165
  obj = c.new *a
166
166
  obj
167
167
  end
@@ -172,10 +172,6 @@ class Prototype
172
172
  end
173
173
 
174
174
  class Object
175
- def Prototype *a, &b
176
- Prototype.new *a, &b
177
- end
178
- def prototype *a, &b
179
- Prototype.new *a, &b
180
- end
175
+ def Prototype(*a, &b) Prototype.new *a, &b end
176
+ def prototype(*a, &b) Prototype.new *a, &b end
181
177
  end
File without changes
data/samples/h.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'prototype'
2
+
3
+ proto = prototype{
4
+ a 1
5
+ b 1
6
+ c 40
7
+
8
+ sum { a + b + c }
9
+ }
10
+
11
+ p proto.sum
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: prototype
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2006-07-12 00:00:00.000000 -06:00
6
+ version: 0.2.0
7
+ date: 2006-07-13 00:00:00.000000 -06:00
8
8
  summary: prototype
9
9
  require_paths:
10
10
  - lib
@@ -34,8 +34,11 @@ files:
34
34
  - gemspec.rb
35
35
  - samples
36
36
  - README
37
- - lib/prototype-0.0.0.rb
37
+ - README.tmpl
38
+ - gen_readme.rb
39
+ - prototype-0.2.0.gem
38
40
  - lib/prototype.rb
41
+ - lib/prototype-0.2.0.rb
39
42
  - samples/c.rb
40
43
  - samples/a.rb
41
44
  - samples/b.rb
@@ -43,10 +46,21 @@ files:
43
46
  - samples/e.rb
44
47
  - samples/f.rb
45
48
  - samples/g.rb
49
+ - samples/h.rb
46
50
  test_files: []
47
51
  rdoc_options: []
48
52
  extra_rdoc_files: []
49
53
  executables: []
50
54
  extensions: []
51
55
  requirements: []
52
- dependencies: []
56
+ dependencies:
57
+ - !ruby/object:Gem::Dependency
58
+ name: attributes
59
+ version_requirement:
60
+ version_requirements: !ruby/object:Gem::Version::Requirement
61
+ requirements:
62
+ -
63
+ - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: "3.0"
66
+ version:
@@ -1,181 +0,0 @@
1
-
2
- #
3
- # http://en.wikipedia.org/wiki/Prototype-based_programming
4
- #
5
-
6
- class Prototype
7
- VERSION = '0.1.0'
8
-
9
- #
10
- # inline my attribute.rb file here
11
- #
12
- module Attrbiutes
13
- def attributes *a, &b
14
- unless a.empty?
15
- hashes, names = a.partition{|x| Hash === x}
16
-
17
- names_and_defaults = {}
18
- hashes.each{|h| names_and_defaults.update h}
19
- names.each{|name| names_and_defaults.update name => nil}
20
-
21
- names_and_defaults.each do |name, default|
22
- init = b || lambda { default }
23
- ivar = "@#{ name }"
24
- getter = "#{ name }"
25
- setter = "#{ name }="
26
- query = "#{ name }?"
27
-
28
- define_method(setter) do |value|
29
- instance_variable_set ivar, value
30
- end
31
-
32
- define_method(getter) do |*value|
33
- unless value.empty?
34
- send setter, value.shift
35
- else
36
- defined = instance_eval "defined? #{ ivar }"
37
- unless defined
38
- send setter, instance_eval(&init)
39
- end
40
- instance_variable_get ivar
41
- end
42
- end
43
-
44
- alias_method query, getter
45
-
46
- (attributes << name).uniq!
47
- attributes
48
- end
49
- else
50
- @attributes ||= []
51
- end
52
- end
53
-
54
- def attribute *a, &b
55
- attributes *a, &b
56
- end
57
- end
58
-
59
- module ClassMethods
60
- include Attrbiutes
61
-
62
- def method_missing m, *a, &b
63
- ivar = "@#{ m }"
64
- if a.size == 0
65
- if defined? ivar
66
- instance_variable_get ivar
67
- else
68
- super
69
- end
70
- elsif a.size == 1
71
- instance_variable_set ivar, a.shift
72
- else
73
- super
74
- end
75
- end
76
- end
77
-
78
- module InstanceMethods
79
- def initialize(*a, &b)
80
- __protoinit__
81
- super
82
- end
83
-
84
- def __protoinit__
85
- self.class.__prototable__.each do |ivar, value|
86
- defined = instance_eval "defined? #{ ivar }"
87
- unless defined
88
- instance_variable_set ivar, value
89
- end
90
-
91
- a = ivar[%r/\w+/]
92
- #defined = respond_to? a
93
- defined = self.class.module_eval{ attributes }.include? a
94
- unless defined
95
- self.class.module_eval{ attribute a }
96
- end
97
- end
98
- end
99
-
100
- def extend *a, &b
101
- unless a.empty?
102
- super
103
- else
104
- self.class.__prototype__ &b
105
- __protoinit__
106
- self
107
- end
108
- end
109
-
110
- def clone *a, &b
111
- obj = prototype(self.class, *a, &b)
112
- instance_variables.each do |ivar|
113
- value = instance_variable_get ivar
114
- obj.instance_variable_set ivar, value
115
- end
116
- obj
117
- end
118
- end
119
-
120
- module Prototype
121
- def __prototable__ # uses const to avoid copying instance var
122
- if const_defined? 'PROTOTABLE'
123
- const_get 'PROTOTABLE'
124
- else
125
- const_set 'PROTOTABLE', {}
126
- end
127
- end
128
-
129
- def __prototype__ &b
130
- return unless b
131
-
132
- module_eval &b
133
-
134
- table =
135
- instance_variables.inject({}) do |t,ivar|
136
- value =
137
- instance_eval do
138
- begin
139
- instance_variable_get ivar
140
- ensure
141
- remove_instance_variable ivar
142
- end
143
- end
144
- t.update ivar => value
145
- end
146
-
147
- __prototable__.update table
148
- end
149
-
150
- def self.extend_object other
151
- other.extend ClassMethods
152
- other.module_eval{ include InstanceMethods }
153
- super
154
- end
155
- end
156
-
157
- class << self
158
- def new parent = Object, *a, &b
159
- parent = parent.class unless Class === parent
160
- c = Class.new parent
161
- c.extend Prototype
162
- prototable = parent.const_get 'PROTOTABLE' rescue nil
163
- c.__prototable__.update prototable if prototable
164
- c.__prototype__ &b
165
- obj = c.new *a
166
- obj
167
- end
168
-
169
- alias_method "exnihilo", "new"
170
- alias_method "ex_nihilo", "new"
171
- end
172
- end
173
-
174
- class Object
175
- def Prototype *a, &b
176
- Prototype.new *a, &b
177
- end
178
- def prototype *a, &b
179
- Prototype.new *a, &b
180
- end
181
- end