prototype 0.0.0 → 0.1.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
@@ -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