fattr 1.1.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +62 -16
- data/README.erb +10 -8
- data/Rakefile +1 -0
- data/fattr.gemspec +3 -2
- data/lib/fattr.rb +73 -33
- data/samples/c.rb +4 -4
- data/samples/e.rb +0 -1
- data/samples/f.rb +1 -1
- data/samples/g.rb +1 -1
- data/samples/h.rb +29 -0
- data/test/fattr.rb +32 -0
- metadata +8 -8
data/README
CHANGED
@@ -5,15 +5,12 @@ INSTALL
|
|
5
5
|
gem install fattrs
|
6
6
|
|
7
7
|
URIS
|
8
|
-
http://
|
8
|
+
http://github.com/ahoward/fattr
|
9
9
|
http://rubyforge.org/projects/codeforpeople/
|
10
|
+
http://codeforpeople.com/
|
10
11
|
|
11
12
|
SYNOPSIS
|
12
|
-
fattr.rb is a "fatter attr" for ruby
|
13
|
-
|
14
|
-
fattr.rb supercedes attributes.rb as that library, even though it added only
|
15
|
-
one method to the global namespace, collided too frequently with user code -
|
16
|
-
in particular rails' code.
|
13
|
+
fattr.rb is a "fatter attr" for ruby
|
17
14
|
|
18
15
|
the implementation of fattr.rb borrows many of the best ideas from the
|
19
16
|
metakoans.rb ruby quiz
|
@@ -21,7 +18,7 @@ SYNOPSIS
|
|
21
18
|
http://www.rubyquiz.com/quiz67.html
|
22
19
|
|
23
20
|
in particular the solutions of Christian Neukirchen and Florian Gross along
|
24
|
-
with concepts from
|
21
|
+
with concepts from my original traits.rb lib
|
25
22
|
|
26
23
|
key features provided by fattrs are
|
27
24
|
|
@@ -49,7 +46,9 @@ SYNOPSIS
|
|
49
46
|
|
50
47
|
- shortcuts for adding class/module level fattrs
|
51
48
|
|
52
|
-
|
49
|
+
- class inheritable attributes
|
50
|
+
|
51
|
+
all this in 156 lines of code
|
53
52
|
|
54
53
|
SAMPLES
|
55
54
|
|
@@ -126,17 +125,17 @@ SAMPLES
|
|
126
125
|
~ > cat samples/c.rb
|
127
126
|
|
128
127
|
#
|
129
|
-
# multiple
|
128
|
+
# multiple name=>default pairs can be given
|
130
129
|
#
|
131
130
|
require 'fattr'
|
132
131
|
|
133
132
|
class C
|
134
|
-
fattrs 'x'
|
133
|
+
fattrs 'x' => 0b101000, 'y' => 0b10
|
135
134
|
end
|
136
135
|
|
137
136
|
c = C.new
|
138
|
-
|
139
|
-
p
|
137
|
+
z = c.x + c.y
|
138
|
+
p z #=> 42
|
140
139
|
|
141
140
|
~ > ruby samples/c.rb
|
142
141
|
|
@@ -206,7 +205,6 @@ SAMPLES
|
|
206
205
|
|
207
206
|
conf = Config.new{
|
208
207
|
host 'codeforpeople.org'
|
209
|
-
|
210
208
|
port 80
|
211
209
|
}
|
212
210
|
|
@@ -214,7 +212,7 @@ SAMPLES
|
|
214
212
|
|
215
213
|
~ > ruby samples/e.rb
|
216
214
|
|
217
|
-
#<Config:
|
215
|
+
#<Config:0x2cd1c @port=80, @host="codeforpeople.org">
|
218
216
|
|
219
217
|
|
220
218
|
<========< samples/f.rb >========>
|
@@ -234,7 +232,7 @@ SAMPLES
|
|
234
232
|
42 => 'DEBUG',
|
235
233
|
}
|
236
234
|
|
237
|
-
class <<
|
235
|
+
class << Logging
|
238
236
|
fattr 'level' => 42
|
239
237
|
fattr('level_name'){ Level_names[level] }
|
240
238
|
end
|
@@ -260,7 +258,7 @@ SAMPLES
|
|
260
258
|
require 'fattr'
|
261
259
|
|
262
260
|
class C
|
263
|
-
class <<
|
261
|
+
class << C
|
264
262
|
fattr 'a' => 4
|
265
263
|
end
|
266
264
|
|
@@ -274,8 +272,56 @@ SAMPLES
|
|
274
272
|
"42"
|
275
273
|
|
276
274
|
|
275
|
+
<========< samples/h.rb >========>
|
276
|
+
|
277
|
+
~ > cat samples/h.rb
|
278
|
+
|
279
|
+
#
|
280
|
+
# class variable inheritance is supported simply
|
281
|
+
#
|
282
|
+
require 'fattr'
|
283
|
+
|
284
|
+
class A
|
285
|
+
Fattr :x, :default => 42, :inheritable => true
|
286
|
+
end
|
287
|
+
|
288
|
+
class B < A
|
289
|
+
end
|
290
|
+
|
291
|
+
class C < B
|
292
|
+
end
|
293
|
+
|
294
|
+
p C.x #=> 42
|
295
|
+
|
296
|
+
A.x = 42.0
|
297
|
+
B.x = 'forty-two'
|
298
|
+
|
299
|
+
p A.x #=> 42.0
|
300
|
+
p B.x #=> 'forty-two'
|
301
|
+
p C.x #=> 42
|
302
|
+
|
303
|
+
C.x! # re-initialize from closest ancestor (B)
|
304
|
+
|
305
|
+
p A.x #=> 42.0
|
306
|
+
p B.x #=> 'forty-two'
|
307
|
+
p C.x #=> 'forty-two'
|
308
|
+
|
309
|
+
~ > ruby samples/h.rb
|
310
|
+
|
311
|
+
42
|
312
|
+
42.0
|
313
|
+
"forty-two"
|
314
|
+
42
|
315
|
+
42.0
|
316
|
+
"forty-two"
|
317
|
+
"forty-two"
|
318
|
+
|
319
|
+
|
277
320
|
|
278
321
|
HISTORY
|
322
|
+
2.0.0:
|
323
|
+
support class/module inheritable attributes
|
324
|
+
|
279
325
|
1.1.0:
|
280
326
|
ruby19 testing. move to github.
|
281
327
|
|
data/README.erb
CHANGED
@@ -5,15 +5,12 @@ INSTALL
|
|
5
5
|
gem install fattrs
|
6
6
|
|
7
7
|
URIS
|
8
|
-
http://
|
8
|
+
http://github.com/ahoward/fattr
|
9
9
|
http://rubyforge.org/projects/codeforpeople/
|
10
|
+
http://codeforpeople.com/
|
10
11
|
|
11
12
|
SYNOPSIS
|
12
|
-
fattr.rb is a "fatter attr" for ruby
|
13
|
-
|
14
|
-
fattr.rb supercedes attributes.rb as that library, even though it added only
|
15
|
-
one method to the global namespace, collided too frequently with user code -
|
16
|
-
in particular rails' code.
|
13
|
+
fattr.rb is a "fatter attr" for ruby
|
17
14
|
|
18
15
|
the implementation of fattr.rb borrows many of the best ideas from the
|
19
16
|
metakoans.rb ruby quiz
|
@@ -21,7 +18,7 @@ SYNOPSIS
|
|
21
18
|
http://www.rubyquiz.com/quiz67.html
|
22
19
|
|
23
20
|
in particular the solutions of Christian Neukirchen and Florian Gross along
|
24
|
-
with concepts from
|
21
|
+
with concepts from my original traits.rb lib
|
25
22
|
|
26
23
|
key features provided by fattrs are
|
27
24
|
|
@@ -49,12 +46,17 @@ SYNOPSIS
|
|
49
46
|
|
50
47
|
- shortcuts for adding class/module level fattrs
|
51
48
|
|
52
|
-
|
49
|
+
- class inheritable attributes
|
50
|
+
|
51
|
+
all this in 156 lines of code
|
53
52
|
|
54
53
|
SAMPLES
|
55
54
|
<%= samples %>
|
56
55
|
|
57
56
|
HISTORY
|
57
|
+
2.0.0:
|
58
|
+
support class/module inheritable attributes
|
59
|
+
|
58
60
|
1.1.0:
|
59
61
|
ruby19 testing. move to github.
|
60
62
|
|
data/Rakefile
CHANGED
@@ -64,6 +64,7 @@ task :gemspec do
|
|
64
64
|
|
65
65
|
Gem::Specification::new do |spec|
|
66
66
|
spec.name = #{ lib.inspect }
|
67
|
+
spec.description = 'fattr.rb is a "fatter attr" for ruby'
|
67
68
|
spec.version = #{ version.inspect }
|
68
69
|
spec.platform = Gem::Platform::RUBY
|
69
70
|
spec.summary = #{ lib.inspect }
|
data/fattr.gemspec
CHANGED
@@ -3,11 +3,12 @@
|
|
3
3
|
|
4
4
|
Gem::Specification::new do |spec|
|
5
5
|
spec.name = "fattr"
|
6
|
-
spec.
|
6
|
+
spec.description = 'fattr.rb is a "fatter attr" for ruby'
|
7
|
+
spec.version = "2.0.0"
|
7
8
|
spec.platform = Gem::Platform::RUBY
|
8
9
|
spec.summary = "fattr"
|
9
10
|
|
10
|
-
spec.files = ["fattr.gemspec", "lib", "lib/fattr.rb", "Rakefile", "README", "README.erb", "samples", "samples/a.rb", "samples/b.rb", "samples/c.rb", "samples/d.rb", "samples/e.rb", "samples/f.rb", "samples/g.rb", "test", "test/fattr.rb"]
|
11
|
+
spec.files = ["fattr.gemspec", "lib", "lib/fattr.rb", "Rakefile", "README", "README.erb", "samples", "samples/a.rb", "samples/b.rb", "samples/c.rb", "samples/d.rb", "samples/e.rb", "samples/f.rb", "samples/g.rb", "samples/h.rb", "test", "test/fattr.rb"]
|
11
12
|
spec.executables = []
|
12
13
|
|
13
14
|
|
data/lib/fattr.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Fattr
|
2
|
-
Fattr::
|
3
|
-
def self.version() Fattr::
|
2
|
+
Fattr::Version = '2.0.0' unless Fattr.const_defined?(:Version)
|
3
|
+
def self.version() Fattr::Version end
|
4
4
|
|
5
5
|
class List < ::Array
|
6
6
|
def << element
|
@@ -13,12 +13,12 @@ module Fattr
|
|
13
13
|
|
14
14
|
def index!
|
15
15
|
@index ||= Hash.new
|
16
|
-
each{|element| @index[element] = true}
|
16
|
+
each{|element| @index[element.to_s] = true}
|
17
17
|
end
|
18
18
|
|
19
|
-
def include?
|
19
|
+
def include?(element)
|
20
20
|
@index ||= Hash.new
|
21
|
-
@index[element] ? true : false
|
21
|
+
@index[element.to_s] ? true : false
|
22
22
|
end
|
23
23
|
|
24
24
|
def initializers
|
@@ -26,33 +26,79 @@ module Fattr
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
def fattrs
|
30
|
-
unless
|
29
|
+
def fattrs(*args, &block)
|
30
|
+
unless args.empty?
|
31
31
|
returned = Hash.new
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
args.flatten!
|
34
|
+
args.compact!
|
35
|
+
|
36
|
+
all_hashes = args.all?{|arg| Hash===arg}
|
37
|
+
|
38
|
+
names_and_configs = {}
|
39
|
+
|
40
|
+
if all_hashes
|
41
|
+
args.each do |hash|
|
42
|
+
hash.each do |key, val|
|
43
|
+
name = key.to_s
|
44
|
+
config = Hash===val ? val : {:default => val}
|
45
|
+
names_and_configs[name] = config
|
46
|
+
end
|
47
|
+
end
|
48
|
+
else
|
49
|
+
config = Hash===args.last ? args.pop : {}
|
50
|
+
names = args.select{|arg| Symbol===arg or String===arg}.map{|arg| arg.to_s}
|
51
|
+
names.each do |name|
|
52
|
+
names_and_configs[name] = config
|
53
|
+
end
|
54
|
+
end
|
37
55
|
|
38
56
|
initializers = __fattrs__.initializers
|
39
57
|
|
40
|
-
|
41
|
-
raise
|
58
|
+
names_and_configs.each do |name, config|
|
59
|
+
raise(NameError, "bad instance variable name '@#{ name }'") if("@#{ name }" =~ %r/[!?=]$/o)
|
60
|
+
|
42
61
|
name = name.to_s
|
43
62
|
|
44
|
-
|
63
|
+
default = nil
|
64
|
+
default = config[:default] if config.has_key?(:default)
|
65
|
+
default = config['default'] if config.has_key?('default')
|
66
|
+
|
67
|
+
inheritable = false
|
68
|
+
if Class===self
|
69
|
+
inheritable = config[:inheritable] if config.has_key?(:inheritable)
|
70
|
+
inheritable = config['inheritable'] if config.has_key?('inheritable')
|
71
|
+
end
|
72
|
+
|
73
|
+
initialize = (
|
74
|
+
block || (
|
75
|
+
unless inheritable
|
76
|
+
lambda{ default }
|
77
|
+
else
|
78
|
+
lambda do
|
79
|
+
if ancestors[1..-1].any?{|ancestor| ancestor.Fattrs.include?(name)}
|
80
|
+
ancestors[1].send(name)
|
81
|
+
else
|
82
|
+
default
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
)
|
87
|
+
)
|
88
|
+
|
45
89
|
initializer = lambda do |this|
|
46
|
-
Object.instance_method('instance_eval').bind(this).call
|
90
|
+
Object.instance_method('instance_eval').bind(this).call(&initialize)
|
47
91
|
end
|
92
|
+
|
48
93
|
initializer_id = initializer.object_id
|
94
|
+
|
49
95
|
__fattrs__.initializers[name] = initializer
|
50
96
|
|
51
97
|
compile = lambda do |code|
|
52
98
|
begin
|
53
|
-
module_eval
|
99
|
+
module_eval(code)
|
54
100
|
rescue SyntaxError
|
55
|
-
raise
|
101
|
+
raise(SyntaxError, "\n#{ code }\n")
|
56
102
|
end
|
57
103
|
end
|
58
104
|
|
@@ -118,36 +164,30 @@ module Fattr
|
|
118
164
|
end
|
119
165
|
end
|
120
166
|
|
121
|
-
%w( __fattrs__ __fattr__ fattr ).each{|dst| alias_method
|
167
|
+
%w( __fattrs__ __fattr__ fattr ).each{|dst| alias_method(dst, 'fattrs')}
|
122
168
|
end
|
123
169
|
|
124
170
|
class Module
|
125
171
|
include Fattr
|
126
172
|
|
127
|
-
def Fattrs(*
|
173
|
+
def Fattrs(*args, &block)
|
128
174
|
class << self
|
129
175
|
self
|
130
|
-
end.module_eval
|
131
|
-
fattrs(*a, &b)
|
132
|
-
end
|
176
|
+
end.module_eval{ __fattrs__(*args, &block) }
|
133
177
|
end
|
134
178
|
|
135
|
-
def Fattr(*
|
179
|
+
def Fattr(*args, &block)
|
136
180
|
class << self
|
137
181
|
self
|
138
|
-
end.module_eval
|
139
|
-
fattr(*a, &b)
|
140
|
-
end
|
182
|
+
end.module_eval{ __fattr__(*args, &block) }
|
141
183
|
end
|
142
184
|
end
|
143
185
|
|
144
186
|
class Object
|
145
|
-
def fattrs
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
end
|
150
|
-
sc.fattrs *a, &b
|
187
|
+
def fattrs(*args, &block)
|
188
|
+
class << self
|
189
|
+
self
|
190
|
+
end.__fattrs__(*args, &block)
|
151
191
|
end
|
152
|
-
%w( __fattrs__ __fattr__ fattr ).each{|dst| alias_method
|
192
|
+
%w( __fattrs__ __fattr__ fattr ).each{|dst| alias_method(dst, 'fattrs')}
|
153
193
|
end
|
data/samples/c.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
#
|
2
|
-
# multiple
|
2
|
+
# multiple name=>default pairs can be given
|
3
3
|
#
|
4
4
|
require 'fattr'
|
5
5
|
|
6
6
|
class C
|
7
|
-
fattrs 'x'
|
7
|
+
fattrs 'x' => 0b101000, 'y' => 0b10
|
8
8
|
end
|
9
9
|
|
10
10
|
c = C.new
|
11
|
-
|
12
|
-
p
|
11
|
+
z = c.x + c.y
|
12
|
+
p z #=> 42
|
data/samples/e.rb
CHANGED
data/samples/f.rb
CHANGED
data/samples/g.rb
CHANGED
data/samples/h.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#
|
2
|
+
# class variable inheritance is supported simply
|
3
|
+
#
|
4
|
+
require 'fattr'
|
5
|
+
|
6
|
+
class A
|
7
|
+
Fattr :x, :default => 42, :inheritable => true
|
8
|
+
end
|
9
|
+
|
10
|
+
class B < A
|
11
|
+
end
|
12
|
+
|
13
|
+
class C < B
|
14
|
+
end
|
15
|
+
|
16
|
+
p C.x #=> 42
|
17
|
+
|
18
|
+
A.x = 42.0
|
19
|
+
B.x = 'forty-two'
|
20
|
+
|
21
|
+
p A.x #=> 42.0
|
22
|
+
p B.x #=> 'forty-two'
|
23
|
+
p C.x #=> 42
|
24
|
+
|
25
|
+
C.x! # re-initialize from closest ancestor (B)
|
26
|
+
|
27
|
+
p A.x #=> 42.0
|
28
|
+
p B.x #=> 'forty-two'
|
29
|
+
p C.x #=> 'forty-two'
|
data/test/fattr.rb
CHANGED
@@ -60,6 +60,38 @@ Testing Fattr do
|
|
60
60
|
m = Module.new{ Fattr :a => 42 }
|
61
61
|
assert{ m.a==42 }
|
62
62
|
end
|
63
|
+
|
64
|
+
testing 'that fattrs support simple class inheritable attributes' do
|
65
|
+
a = Class.new{ Fattr :x, :default => 42, :inheritable => true }
|
66
|
+
b = Class.new(a)
|
67
|
+
c = Class.new(b)
|
68
|
+
def a.name() 'a' end
|
69
|
+
def b.name() 'b' end
|
70
|
+
def c.name() 'c' end
|
71
|
+
assert{ c.x==42 }
|
72
|
+
assert{ b.x==42 }
|
73
|
+
assert{ a.x==42 }
|
74
|
+
assert{ b.x=42.0 }
|
75
|
+
assert{ b.x==42.0 }
|
76
|
+
assert{ a.x==42 }
|
77
|
+
assert{ a.x='forty-two' }
|
78
|
+
assert{ a.x=='forty-two' }
|
79
|
+
assert{ b.x==42.0 }
|
80
|
+
assert{ b.x! }
|
81
|
+
assert{ b.x=='forty-two' }
|
82
|
+
assert{ b.x='FORTY-TWO' }
|
83
|
+
assert{ c.x! }
|
84
|
+
assert{ c.x=='FORTY-TWO' }
|
85
|
+
end
|
86
|
+
|
87
|
+
testing 'a list of fattrs can be declared at once' do
|
88
|
+
list = %w( a b c )
|
89
|
+
c = Class.new{ fattrs list }
|
90
|
+
list.each do |attr|
|
91
|
+
assert{ c.fattrs.include?(attr.to_s) }
|
92
|
+
assert{ c.fattrs.include?(attr.to_sym) }
|
93
|
+
end
|
94
|
+
end
|
63
95
|
end
|
64
96
|
|
65
97
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fattr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ara T. Howard
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-10-11 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description:
|
16
|
+
description: fattr.rb is a "fatter attr" for ruby
|
17
17
|
email: ara.t.howard@gmail.com
|
18
18
|
executables: []
|
19
19
|
|
@@ -23,12 +23,10 @@ extra_rdoc_files: []
|
|
23
23
|
|
24
24
|
files:
|
25
25
|
- fattr.gemspec
|
26
|
-
- lib
|
27
26
|
- lib/fattr.rb
|
28
27
|
- Rakefile
|
29
28
|
- README
|
30
29
|
- README.erb
|
31
|
-
- samples
|
32
30
|
- samples/a.rb
|
33
31
|
- samples/b.rb
|
34
32
|
- samples/c.rb
|
@@ -36,10 +34,12 @@ files:
|
|
36
34
|
- samples/e.rb
|
37
35
|
- samples/f.rb
|
38
36
|
- samples/g.rb
|
39
|
-
-
|
37
|
+
- samples/h.rb
|
40
38
|
- test/fattr.rb
|
41
39
|
has_rdoc: true
|
42
40
|
homepage: http://github.com/ahoward/fattr/tree/master
|
41
|
+
licenses: []
|
42
|
+
|
43
43
|
post_install_message:
|
44
44
|
rdoc_options: []
|
45
45
|
|
@@ -60,9 +60,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
60
|
requirements: []
|
61
61
|
|
62
62
|
rubyforge_project: codeforpeople
|
63
|
-
rubygems_version: 1.3.
|
63
|
+
rubygems_version: 1.3.5
|
64
64
|
signing_key:
|
65
|
-
specification_version:
|
65
|
+
specification_version: 3
|
66
66
|
summary: fattr
|
67
67
|
test_files:
|
68
68
|
- test/fattr.rb
|