prototype 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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