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 CHANGED
@@ -5,15 +5,12 @@ INSTALL
5
5
  gem install fattrs
6
6
 
7
7
  URIS
8
- http://codeforpeople.com/lib/ruby
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 the original traits.rb lib
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
- all this in < 100 lines of code
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 values may by given, plain names and key/val pairs may be mixed.
128
+ # multiple name=>default pairs can be given
130
129
  #
131
130
  require 'fattr'
132
131
 
133
132
  class C
134
- fattrs 'x', 'y' => 0b101000, 'z' => 0b10
133
+ fattrs 'x' => 0b101000, 'y' => 0b10
135
134
  end
136
135
 
137
136
  c = C.new
138
- c.x = c.y + c.z
139
- p c.x #=> 42
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:0x2de88 @port=80, @host="codeforpeople.org">
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 << self
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 << self
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://codeforpeople.com/lib/ruby
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 the original traits.rb lib
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
- all this in < 100 lines of code
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.version = "1.1.0"
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::VERSION = '1.1.0' unless Fattr.const_defined?(:VERSION)
3
- def self.version() Fattr::VERSION end
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? element
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 *a, &b
30
- unless a.empty?
29
+ def fattrs(*args, &block)
30
+ unless args.empty?
31
31
  returned = Hash.new
32
32
 
33
- hashes, names = a.partition{|x| Hash === x}
34
- names_and_defaults = {}
35
- hashes.each{|h| names_and_defaults.update h}
36
- names.flatten.compact.each{|name| names_and_defaults.update name => nil}
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
- names_and_defaults.each do |name, default|
41
- raise NameError, "bad instance variable name '@#{ name }'" if "@#{ name }" =~ %r/[!?=]$/o
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
- initialize = b || lambda { default }
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 &initialize
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 code
99
+ module_eval(code)
54
100
  rescue SyntaxError
55
- raise SyntaxError, "\n#{ code }\n"
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 dst, 'fattrs'}
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(*a, &b)
173
+ def Fattrs(*args, &block)
128
174
  class << self
129
175
  self
130
- end.module_eval do
131
- fattrs(*a, &b)
132
- end
176
+ end.module_eval{ __fattrs__(*args, &block) }
133
177
  end
134
178
 
135
- def Fattr(*a, &b)
179
+ def Fattr(*args, &block)
136
180
  class << self
137
181
  self
138
- end.module_eval do
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 *a, &b
146
- sc =
147
- class << self
148
- self
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 dst, 'fattrs'}
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 values may by given, plain names and key/val pairs may be mixed.
2
+ # multiple name=>default pairs can be given
3
3
  #
4
4
  require 'fattr'
5
5
 
6
6
  class C
7
- fattrs 'x', 'y' => 0b101000, 'z' => 0b10
7
+ fattrs 'x' => 0b101000, 'y' => 0b10
8
8
  end
9
9
 
10
10
  c = C.new
11
- c.x = c.y + c.z
12
- p c.x #=> 42
11
+ z = c.x + c.y
12
+ p z #=> 42
data/samples/e.rb CHANGED
@@ -11,7 +11,6 @@
11
11
 
12
12
  conf = Config.new{
13
13
  host 'codeforpeople.org'
14
-
15
14
  port 80
16
15
  }
17
16
 
data/samples/f.rb CHANGED
@@ -11,7 +11,7 @@
11
11
  42 => 'DEBUG',
12
12
  }
13
13
 
14
- class << self
14
+ class << Logging
15
15
  fattr 'level' => 42
16
16
  fattr('level_name'){ Level_names[level] }
17
17
  end
data/samples/g.rb CHANGED
@@ -5,7 +5,7 @@
5
5
  require 'fattr'
6
6
 
7
7
  class C
8
- class << self
8
+ class << C
9
9
  fattr 'a' => 4
10
10
  end
11
11
 
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: 1.1.0
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-09-28 00:00:00 -06:00
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
- - test
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.1
63
+ rubygems_version: 1.3.5
64
64
  signing_key:
65
- specification_version: 2
65
+ specification_version: 3
66
66
  summary: fattr
67
67
  test_files:
68
68
  - test/fattr.rb