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 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