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 +67 -1
- data/lib/prototype-0.0.0.rb +144 -41
- data/lib/prototype.rb +144 -41
- data/samples/c.rb +16 -1
- data/samples/d.rb +12 -0
- data/samples/e.rb +8 -0
- data/samples/f.rb +9 -0
- data/samples/g.rb +11 -0
- metadata +5 -2
- data/prototype.rb +0 -74
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
|
data/lib/prototype-0.0.0.rb
CHANGED
@@ -4,75 +4,178 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
class Prototype
|
7
|
-
VERSION = '0.
|
7
|
+
VERSION = '0.1.0'
|
8
8
|
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
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
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
28
|
+
define_method(setter) do |value|
|
29
|
+
instance_variable_set ivar, value
|
30
|
+
end
|
22
31
|
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
135
|
+
instance_variables.inject({}) do |t,ivar|
|
47
136
|
value =
|
48
|
-
|
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
|
-
|
144
|
+
t.update ivar => value
|
56
145
|
end
|
57
146
|
|
58
|
-
|
147
|
+
__prototable__.update table
|
148
|
+
end
|
59
149
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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.
|
7
|
+
VERSION = '0.1.0'
|
8
8
|
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
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
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
end
|
28
|
+
define_method(setter) do |value|
|
29
|
+
instance_variable_set ivar, value
|
30
|
+
end
|
22
31
|
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
135
|
+
instance_variables.inject({}) do |t,ivar|
|
47
136
|
value =
|
48
|
-
|
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
|
-
|
144
|
+
t.update ivar => value
|
56
145
|
end
|
57
146
|
|
58
|
-
|
147
|
+
__prototable__.update table
|
148
|
+
end
|
59
149
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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 =
|
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
data/samples/f.rb
ADDED
data/samples/g.rb
ADDED
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.
|
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
|