blindgaenger-configurable 0.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,9 +5,11 @@ Little helper to configure ruby instances in a DSLish way.
5
5
 
6
6
  h2. Usage
7
7
 
8
- See the @examples/triangle.rb@ for the example described here.
8
+ See @examples/*.rb@ for all examples described here.
9
9
 
10
- Include it in your class and define some configuration attributes:
10
+ h3. Basic usage (Triangle example)
11
+
12
+ Include @Configurable@ in your class and define some configuration attributes:
11
13
 
12
14
  <pre><code>
13
15
  require 'rubygems'
@@ -51,7 +53,7 @@ Use the configured instances.
51
53
  Of course, feel free to have a look at the "source code":http://github.com/blindgaenger/configurable on Github. ;)
52
54
 
53
55
 
54
- h3. Initalize with the configured key
56
+ h3. Initalize with the configured key (Website example)
55
57
 
56
58
  In some cases the key you use in the @configure@ method should be available in
57
59
  the model as well. Of course, you could specify it again, but that's not necessary.
@@ -81,7 +83,7 @@ the specified key. It's up to you, what you do with it.
81
83
  </code></pre>
82
84
 
83
85
 
84
- h3. Reader, writer or accessor
86
+ h3. Config attributes, readers, writers and accessors (Person example)
85
87
 
86
88
  The basic @attr_*@ methods are available as @config_*@. They create the getter
87
89
  and setter methods as usual. So you can still define which attributes should be
@@ -91,43 +93,45 @@ accessible from the outside world.
91
93
  class Person
92
94
  include Configurable
93
95
 
94
- config_reader :birthday # can't change it
95
- config_writer :nickname # don't even know how they call you
96
- config_accessor :friends # may come and go
96
+ config_attribute :health # can't be given or stolen
97
+ config_reader :birthday # can't change it
98
+ config_writer :nickname # don't even know how they call you
99
+ config_accessor :friends # may come and go
97
100
  end
98
101
 
99
102
  Person.configure 'Bertolt Brecht' do
103
+ health 'good'
100
104
  birthday '1898-02-10'
101
105
  nickname 'Bert'
102
- friends 'Hanns Eisler', 'Karl Valentin'
106
+ friends ['Hanns Eisler', 'Karl Valentin']
103
107
  end
104
108
 
105
109
  brecht = Person['Bertolt Brecht']
106
110
 
111
+ # attribute
112
+ brecht.health #=> NoMethodError
113
+ brecht.health = 'bad' #=> NoMethodError
114
+
107
115
  # reader
108
- brecht.birthday #=> 1898-02-10
109
- begin
110
- brecht.birthday = '2008-12-24'
111
- rescue NoMethodError => ex
112
- end
116
+ brecht.birthday #=> 1898-02-10
117
+ brecht.birthday = '2008-12-24' #=> NoMethodError
113
118
 
114
119
  # writer
115
- brecht.nickname = 'Herr K.'
116
- begin
117
- brecht.nickname
118
- rescue NoMethodError => ex
119
- end
120
+ brecht.nickname = 'Herr K.' #=> 'Herr K.'
121
+ brecht.nickname #=> NoMethodError
120
122
 
121
123
  # accessor
122
- brecht.friends #=> ["Hanns Eisler", "Karl Valentin"]
123
- brecht.friends << 'Carola Neher'
124
- brecht.friends #=> ["Hanns Eisler", "Karl Valentin", "Carola Neher"]
124
+ brecht.friends #=> ["Hanns Eisler", "Karl Valentin"]
125
+ brecht.friends << 'Carola Neher' #=> ["Hanns Eisler", "Karl Valentin", "Carola Neher"]
126
+ brecht.friends #=> ["Hanns Eisler", "Karl Valentin", "Carola Neher"]
125
127
  </code></pre>
126
128
 
127
- You see, all behave the exact same way!
129
+ You see, all behave the exact same way as your attr_* helpers! Except for the new
130
+ config_attribute, which defines the instance variable, but does not share it to
131
+ the outside world.
128
132
 
129
133
 
130
- h3. Use in configuration files
134
+ h3. Use in configuration files (Computer example)
131
135
 
132
136
  Please see @examples/computers.rb@ for the working example.
133
137
 
@@ -193,6 +197,39 @@ Back in your ruby file, load the config and use it as usual.
193
197
  raumstation.type #=> :server
194
198
  </code></pre>
195
199
 
200
+
201
+ h3. Configs with code blocks (Tower example)
202
+
203
+ By providing a block you can define what your @config_*@ method should do. This
204
+ way you can implement for example validations or stacks. Something like this:
205
+
206
+ <pre><code>
207
+ class Tower
208
+ include Configurable
209
+
210
+ attr_reader :stack
211
+
212
+ config_attribute :brick do |color|
213
+ raise "argh, #{color}!!!" if color == 'purple'
214
+ @stack ||= []
215
+ @stack << color
216
+ end
217
+ end
218
+ </code></pre>
219
+
220
+ Now the @brick@ method can be called multiple times. And for the @purple@ color
221
+ you'll get an angry error.
222
+
223
+ <pre><code>
224
+ brick = Tower.configure 'nice' do
225
+ brick 'red'
226
+ brick 'green'
227
+ brick 'green'
228
+ brick 'blue'
229
+ end
230
+ brick.stack #=> ["red", "green", "green", "blue"]
231
+ </code></pre>
232
+
196
233
  That's it!
197
234
 
198
235
 
@@ -1,3 +1,6 @@
1
+ require 'rubygems'
2
+ require 'facets'
3
+
1
4
  module Configurable
2
5
 
3
6
  def self.included(base)
@@ -25,9 +28,11 @@ module Configurable
25
28
  super # should raise the error
26
29
  end
27
30
  else
28
- value = *args
29
- value = block.call(*args) if block_given?
30
- instance_variable_set("@#{name}", value)
31
+ if block_given?
32
+ instance_exec(*args, &block)
33
+ else
34
+ instance_variable_set("@#{name}", *args)
35
+ end
31
36
  end
32
37
  end
33
38
 
@@ -51,6 +56,9 @@ module Configurable
51
56
  config_attr(true, false, *names, &block)
52
57
  end
53
58
 
59
+ def base.config_attribute(*names, &block)
60
+ config_attr(false, false, *names, &block)
61
+ end
54
62
 
55
63
  def base.configure(key, *args, &block)
56
64
  # arity isn't reliable, so just try it
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blindgaenger-configurable
3
3
  version: !ruby/object:Gem::Version
4
- version: "0.1"
4
+ version: "0.2"
5
5
  platform: ruby
6
6
  authors:
7
7
  - blindgaenger
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-18 00:00:00 -08:00
12
+ date: 2009-01-21 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -1,40 +0,0 @@
1
- $:.unshift File.join(File::dirname(__FILE__), '..', 'lib')
2
- require 'configurable'
3
-
4
- class Person
5
- include Configurable
6
-
7
- config_reader :birthday # can't change it
8
- config_writer :nickname # don't even know how they call you
9
- config_accessor :friends # may come and go
10
- end
11
-
12
- Person.configure 'Bertolt Brecht' do
13
- birthday '1898-02-10'
14
- nickname 'Bert'
15
- friends 'Hanns Eisler', 'Karl Valentin'
16
- end
17
-
18
- brecht = Person['Bertolt Brecht']
19
-
20
- # reader
21
- brecht.birthday #=> 1898-02-10
22
- begin
23
- brecht.birthday = '2008-12-24'
24
- rescue NoMethodError => ex
25
- #=> undefined method `birthday=' for #<Person:0xb7c30d04>
26
- end
27
-
28
- # writer
29
- brecht.nickname = 'Herr K.'
30
- begin
31
- brecht.nickname
32
- rescue NoMethodError => ex
33
- #=> super: no superclass method `nickname'
34
- end
35
-
36
- # accessor
37
- brecht.friends #=> ["Hanns Eisler", "Karl Valentin"]
38
- brecht.friends << 'Carola Neher'
39
- brecht.friends #=> ["Hanns Eisler", "Karl Valentin", "Carola Neher"]
40
-
@@ -1,16 +0,0 @@
1
-
2
- desktop 'apfelsaft' do
3
- ip '192.168.0.200'
4
- end
5
-
6
- server 'raumstation' do
7
- ip '192.168.0.201'
8
- end
9
-
10
- server 'wohnserver' do
11
- ip '192.168.0.202'
12
- end
13
-
14
- notebook 'gartenstuhl' do
15
- ip '192.168.0.203'
16
- end
@@ -1,46 +0,0 @@
1
- $:.unshift File.join(File::dirname(__FILE__), '..', 'lib')
2
- require 'configurable'
3
-
4
- class Computer
5
- include Configurable
6
-
7
- attr_accessor :type
8
- config_accessor :hostname
9
- config_accessor :ip
10
-
11
- def initialize(host, type)
12
- @hostname = host
13
- @type = type
14
- end
15
- end
16
-
17
-
18
- # define some DSLish config helpers
19
-
20
- def server(name, &block)
21
- Computer.configure(name, :server, &block)
22
- end
23
-
24
- def desktop(name, &block)
25
- Computer.configure(name, :desktop, &block)
26
- end
27
-
28
- def notebook(name, &block)
29
- Computer.configure(name, :notebook, &block)
30
- end
31
-
32
-
33
- # load the config (here from 'computers.config')
34
- config_file = $0.gsub /#{File.extname($0)}$/, '.config'
35
- load config_file
36
-
37
-
38
- # now use them
39
-
40
- ips = Computer.map {|name, computer| computer.ip }
41
- #=> ["192.168.0.201", "192.168.0.200", "192.168.0.202", "192.168.0.203"]
42
-
43
- Computer['raumstation'] #=> <Computer:0xb7c6e4c4 @type=:server, @hostname="raumstation", @ip="192.168.0.201">
44
- Computer['apfelsaft'] #=> <Computer:0xb7c6e62c @type=:desktop, @hostname="apfelsaft", @ip="192.168.0.200">
45
- Computer['wohnserver'] #=> <Computer:0xb7c6e370 @type=:server, @hostname="wohnserver", @ip="192.168.0.202">
46
- Computer['gartenstuhl'] #=> <Computer:0xb7c6e21c @type=:notebook, @hostname="gartenstuhl", @ip="192.168.0.203">