prototype 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -21,7 +21,9 @@ WHY
21
21
 
22
22
  EXAMPLES
23
23
 
24
+ __________________________________________
24
25
  ~ > cat samples/a.rb
26
+ __________________________________________
25
27
  require 'prototype'
26
28
 
27
29
  singleton = Prototype.new{
@@ -33,13 +35,16 @@ EXAMPLES
33
35
  p singleton.answer
34
36
 
35
37
 
38
+ __________________________________________
36
39
  ~ > ruby samples/a.rb
40
+ __________________________________________
37
41
  42
38
42
 
39
43
 
40
44
 
41
-
45
+ __________________________________________
42
46
  ~ > cat samples/b.rb
47
+ __________________________________________
43
48
  require 'prototype'
44
49
 
45
50
  DB = Prototype.new{
@@ -55,10 +60,71 @@ EXAMPLES
55
60
  DB.connect
56
61
 
57
62
 
63
+ __________________________________________
58
64
  ~ > ruby samples/b.rb
65
+ __________________________________________
59
66
  "localhost"
60
67
  4242
61
68
  ["localhost", 4242]
69
+
70
+
71
+
72
+ __________________________________________
73
+ ~ > cat samples/e.rb
74
+ __________________________________________
75
+ require 'prototype'
76
+
77
+ proto = prototype{
78
+ @a = 40
79
+ @b = 2
80
+ }
81
+
82
+ p(proto.a + proto.b)
83
+
84
+
85
+ ~ > ruby -Ilib samples/e.rb
86
+ 42
87
+
88
+
89
+
90
+ __________________________________________
91
+ ~ > 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
+
101
+ [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) }
102
+
103
+
104
+ ~ > ruby -Ilib samples/f.rb
105
+ 42
106
+ 42
107
+ 42
108
+
109
+
110
+
111
+ __________________________________________
112
+ ~ > cat samples/g.rb
113
+ __________________________________________
114
+ require 'prototype'
115
+
116
+ a = prototype
117
+
118
+ b = prototype(a){ @a, @b, @c = 4, 10, 2 }
119
+
120
+ a.extend{ def answer() a * b + c end }
121
+
122
+ p b.answer
123
+
124
+
125
+ ~ > ruby -Ilib samples/g.rb
126
+ 42
127
+
62
128
 
63
129
 
64
130
  DOCS
@@ -4,75 +4,178 @@
4
4
  #
5
5
 
6
6
  class Prototype
7
- VERSION = '0.0.0'
7
+ VERSION = '0.1.0'
8
8
 
9
- class << self
10
- def version() VERSION end
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}
11
16
 
12
- def new proto = Object, *a, &b
13
- proto = proto.protoclass unless Class === proto
17
+ names_and_defaults = {}
18
+ hashes.each{|h| names_and_defaults.update h}
19
+ names.each{|name| names_and_defaults.update name => nil}
14
20
 
15
- c = Class.new proto
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 }?"
16
27
 
17
- c.module_eval do
18
- define_method(:protoclass) do
19
- c
20
- end
21
- end
28
+ define_method(setter) do |value|
29
+ instance_variable_set ivar, value
30
+ end
22
31
 
23
- c.module_eval <<-code
24
- class << self
25
- def method_missing m, *a, &b
26
- ivar = "@%s" % m
27
- if a.size == 0
28
- if defined? ivar
29
- instance_variable_get ivar
30
- else
31
- super
32
- end
33
- elsif a.size == 1
34
- instance_variable_set ivar, a.shift
35
- attr_accessor m
32
+ define_method(getter) do |*value|
33
+ unless value.empty?
34
+ send setter, value.shift
36
35
  else
37
- super
36
+ defined = instance_eval "defined? #{ ivar }"
37
+ unless defined
38
+ send setter, instance_eval(&init)
39
+ end
40
+ instance_variable_get ivar
38
41
  end
39
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
40
69
  end
41
- code
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
42
83
 
43
- c.module_eval &b if b
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
44
133
 
45
134
  table =
46
- c.instance_variables.inject({}) do |t,ivar|
135
+ instance_variables.inject({}) do |t,ivar|
47
136
  value =
48
- c.instance_eval do
137
+ instance_eval do
49
138
  begin
50
139
  instance_variable_get ivar
51
140
  ensure
52
141
  remove_instance_variable ivar
53
142
  end
54
143
  end
55
- t.update ivar => value
144
+ t.update ivar => value
56
145
  end
57
146
 
58
- c.const_set 'PROTOTABLE', table
147
+ __prototable__.update table
148
+ end
59
149
 
60
- c.module_eval <<-code
61
- def initialize(*a, &b)
62
- PROTOTABLE.each do |ivar, value|
63
- instance_variable_set ivar, value
64
- end
65
- super
66
- end
67
- code
150
+ def self.extend_object other
151
+ other.extend ClassMethods
152
+ other.module_eval{ include InstanceMethods }
153
+ super
154
+ end
155
+ end
68
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
69
165
  obj = c.new *a
70
-
71
166
  obj
72
167
  end
73
168
 
74
169
  alias_method "exnihilo", "new"
75
170
  alias_method "ex_nihilo", "new"
76
- alias_method "clone", "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
77
180
  end
78
181
  end
data/lib/prototype.rb CHANGED
@@ -4,75 +4,178 @@
4
4
  #
5
5
 
6
6
  class Prototype
7
- VERSION = '0.0.0'
7
+ VERSION = '0.1.0'
8
8
 
9
- class << self
10
- def version() VERSION end
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}
11
16
 
12
- def new proto = Object, *a, &b
13
- proto = proto.protoclass unless Class === proto
17
+ names_and_defaults = {}
18
+ hashes.each{|h| names_and_defaults.update h}
19
+ names.each{|name| names_and_defaults.update name => nil}
14
20
 
15
- c = Class.new proto
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 }?"
16
27
 
17
- c.module_eval do
18
- define_method(:protoclass) do
19
- c
20
- end
21
- end
28
+ define_method(setter) do |value|
29
+ instance_variable_set ivar, value
30
+ end
22
31
 
23
- c.module_eval <<-code
24
- class << self
25
- def method_missing m, *a, &b
26
- ivar = "@%s" % m
27
- if a.size == 0
28
- if defined? ivar
29
- instance_variable_get ivar
30
- else
31
- super
32
- end
33
- elsif a.size == 1
34
- instance_variable_set ivar, a.shift
35
- attr_accessor m
32
+ define_method(getter) do |*value|
33
+ unless value.empty?
34
+ send setter, value.shift
36
35
  else
37
- super
36
+ defined = instance_eval "defined? #{ ivar }"
37
+ unless defined
38
+ send setter, instance_eval(&init)
39
+ end
40
+ instance_variable_get ivar
38
41
  end
39
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
40
69
  end
41
- code
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
42
83
 
43
- c.module_eval &b if b
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
44
133
 
45
134
  table =
46
- c.instance_variables.inject({}) do |t,ivar|
135
+ instance_variables.inject({}) do |t,ivar|
47
136
  value =
48
- c.instance_eval do
137
+ instance_eval do
49
138
  begin
50
139
  instance_variable_get ivar
51
140
  ensure
52
141
  remove_instance_variable ivar
53
142
  end
54
143
  end
55
- t.update ivar => value
144
+ t.update ivar => value
56
145
  end
57
146
 
58
- c.const_set 'PROTOTABLE', table
147
+ __prototable__.update table
148
+ end
59
149
 
60
- c.module_eval <<-code
61
- def initialize(*a, &b)
62
- PROTOTABLE.each do |ivar, value|
63
- instance_variable_set ivar, value
64
- end
65
- super
66
- end
67
- code
150
+ def self.extend_object other
151
+ other.extend ClassMethods
152
+ other.module_eval{ include InstanceMethods }
153
+ super
154
+ end
155
+ end
68
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
69
165
  obj = c.new *a
70
-
71
166
  obj
72
167
  end
73
168
 
74
169
  alias_method "exnihilo", "new"
75
170
  alias_method "ex_nihilo", "new"
76
- alias_method "clone", "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
77
180
  end
78
181
  end
data/samples/c.rb CHANGED
@@ -4,7 +4,22 @@ a = Prototype.new{
4
4
  def method() 42 end
5
5
  }
6
6
 
7
- b = Prototype.clone a
7
+ b = a.clone
8
8
 
9
+ p a.method
9
10
  p b.method
10
11
 
12
+ a.extend{
13
+ def method2() '42' end
14
+ }
15
+
16
+ p a.method2
17
+ p b.method2
18
+
19
+ b.extend{
20
+ def method3() 42.0 end
21
+ }
22
+
23
+ p b.method3
24
+ p a.method3 # throws error!
25
+
data/samples/d.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'prototype'
2
+
3
+ proto = prototype{ attributes 'a' => 1, 'b' => 2, 'c' => 3 }
4
+ proto = prototype{ a 1; b 2; c 3 }
5
+
6
+ %w( a b c ).each{|attr| p proto.send(attr)}
7
+
8
+ clone = proto.clone
9
+ proto.c = 42
10
+
11
+ %w( a b c ).each{|attr| p proto.send(attr)}
12
+ %w( a b c ).each{|attr| p clone.send(attr)}
data/samples/e.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'prototype'
2
+
3
+ proto = prototype{
4
+ @a = 40
5
+ @b = 2
6
+ }
7
+
8
+ p(proto.a + proto.b)
data/samples/f.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'prototype'
2
+
3
+ a = prototype{ attributes 'a' => 4, 'b' => 10, 'c' => 2}
4
+
5
+ b = prototype{ a 4; b 10; c 2 }
6
+
7
+ c = prototype{ @a = 4; @b = 10; @c = 2 }
8
+
9
+ [a, b, c].each{|obj| p(obj.a * obj.b + obj.c) }
data/samples/g.rb ADDED
@@ -0,0 +1,11 @@
1
+
2
+ require 'prototype'
3
+
4
+ a = prototype
5
+
6
+ b = prototype(a){ @a, @b, @c = 4, 10, 2 }
7
+
8
+ a.extend{ def answer() a * b + c end }
9
+
10
+ p b.answer
11
+
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: prototype
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.0
6
+ version: 0.1.0
7
7
  date: 2006-07-12 00:00:00.000000 -06:00
8
8
  summary: prototype
9
9
  require_paths:
@@ -30,7 +30,6 @@ authors:
30
30
  - Ara T. Howard
31
31
  files:
32
32
  - lib
33
- - prototype.rb
34
33
  - install.rb
35
34
  - gemspec.rb
36
35
  - samples
@@ -40,6 +39,10 @@ files:
40
39
  - samples/c.rb
41
40
  - samples/a.rb
42
41
  - samples/b.rb
42
+ - samples/d.rb
43
+ - samples/e.rb
44
+ - samples/f.rb
45
+ - samples/g.rb
43
46
  test_files: []
44
47
  rdoc_options: []
45
48
  extra_rdoc_files: []
data/prototype.rb DELETED
@@ -1,74 +0,0 @@
1
-
2
- #
3
- # http://en.wikipedia.org/wiki/Prototype-based_programming
4
- #
5
-
6
- class Prototype
7
- class << self
8
- def new proto = Object, *a, &b
9
- proto = proto.protoclass unless Class === proto
10
-
11
- c = Class.new proto
12
-
13
- c.module_eval do
14
- define_method(:protoclass) do
15
- c
16
- end
17
- end
18
-
19
- c.module_eval <<-code
20
- class << self
21
- def method_missing m, *a, &b
22
- ivar = "@%s" % m
23
- if a.size == 0
24
- if defined? ivar
25
- instance_variable_get ivar
26
- else
27
- super
28
- end
29
- elsif a.size == 1
30
- instance_variable_set ivar, a.shift
31
- attr_accessor m
32
- else
33
- super
34
- end
35
- end
36
- end
37
- code
38
-
39
- c.module_eval &b if b
40
-
41
- table =
42
- c.instance_variables.inject({}) do |t,ivar|
43
- value =
44
- c.instance_eval do
45
- begin
46
- instance_variable_get ivar
47
- ensure
48
- remove_instance_variable ivar
49
- end
50
- end
51
- t.update ivar => value
52
- end
53
-
54
- c.const_set 'PROTOTABLE', table
55
-
56
- c.module_eval <<-code
57
- def initialize(*a, &b)
58
- PROTOTABLE.each do |ivar, value|
59
- instance_variable_set ivar, value
60
- end
61
- super
62
- end
63
- code
64
-
65
- obj = c.new *a
66
-
67
- obj
68
- end
69
-
70
- alias_method "exnihilo", "new"
71
- alias_method "ex_nihilo", "new"
72
- alias_method "clone", "new"
73
- end
74
- end