fattr 1.1.0 → 2.0.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 +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
|