configatron 4.1.0 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 4.1.1
2
+
3
+ * Fix delayed attributes
4
+
1
5
  === 4.1.0
2
6
 
3
7
  * Fix bugs from BasicObject fallout
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Configatron makes configuring your applications and scripts incredibly easy. No longer is a there a need to use constants or global variables. Now you can use a simple and painless system to configure your life. And, because it's all Ruby, you can do any crazy thing you would like to!
5
5
 
6
- One of the more important changes to V3 is that it now resembles more a `Hash` style interface. You can use `[]`, `fetch`, `each`, etc... Actually the hash notation is more robust since the dot notation won't work for some property names. See section "Differences between dot and hash notation" for more details.
6
+ One of the more important changes to V3 is that it now resembles more a `Hash` style interface. You can use `[]`, `fetch`, `each`, etc... Actually the hash notation is a bit more robust since the dot notation won't work for a few property names (a few public methods from `Configatron::Store` itself).
7
7
 
8
8
  ## Installation
9
9
 
@@ -78,7 +78,7 @@ configatron.email.pop.port # => 110
78
78
 
79
79
  ### Method vs hash access
80
80
 
81
- As a note, method (`configatron.foo`) access will be shadowed by public methods defined on the configatron object. (The configatron object descends from [`BasicObject`](http://apidock.com/ruby/BasicObject) and includes `Kernel`, so it should have a pretty bare set of methods.)
81
+ As a note, method (`configatron.foo`) access will be shadowed by public methods defined on the configatron object. (The configatron object descends from [`BasicObject`](http://apidock.com/ruby/BasicObject) and adds a few methods to resemble the `Hash` API and to play nice with `puts`, so it should have a pretty bare set of methods.)
82
82
 
83
83
  If you need to use keys that are themselves method names, you can just use hash access (`configatron['foo']`).
84
84
 
@@ -35,30 +35,32 @@ module Configatron::DeepClone
35
35
  # You can redistribute it and/or modify it under the same terms of Ruby's license;
36
36
  # either the dual license version in 2003, or any later version.
37
37
  def self.deep_clone( obj=self, cloned={} )
38
- if obj.kind_of?(Configatron::RootStore)
38
+ if Configatron::RootStore === obj
39
39
  # We never actually want to have multiple copies of our
40
40
  # Configatron::RootStore (and every Store has a reference).
41
41
  return obj
42
- elsif cloned.has_key?( obj.object_id )
43
- return cloned[obj.object_id]
42
+ elsif cloned.key?( obj.__id__ )
43
+ return cloned[obj.__id__]
44
44
  else
45
45
  begin
46
46
  cl = obj.clone
47
47
  rescue Exception
48
48
  # unclonnable (TrueClass, Fixnum, ...)
49
- cloned[obj.object_id] = obj
49
+ cloned[obj.__id__] = obj
50
50
  return obj
51
51
  else
52
- cloned[obj.object_id] = cl
53
- cloned[cl.object_id] = cl
54
- if cl.is_a?( Hash )
55
- cl.clone.each { |k,v|
52
+ cloned[obj.__id__] = cl
53
+ cloned[cl.__id__] = cl
54
+ case
55
+ when Configatron::Store === cl then return cl
56
+ when Hash === cl
57
+ cl.clone.each do |k,v|
56
58
  cl[k] = deep_clone( v, cloned )
57
- }
58
- elsif cl.is_a?( Array )
59
- cl.collect! { |v|
59
+ end
60
+ when Array === cl
61
+ cl.collect! do |v|
60
62
  deep_clone( v, cloned )
61
- }
63
+ end
62
64
  end
63
65
  cl.instance_variables.each do |var|
64
66
  v = cl.instance_eval( var.to_s )
@@ -3,7 +3,6 @@ require 'singleton'
3
3
  # This is the root configatron object, and contains methods which
4
4
  # operate on the entire configatron hierarchy.
5
5
  class Configatron::RootStore < BasicObject
6
- include ::Kernel
7
6
  include ::Singleton
8
7
  extend ::Forwardable
9
8
 
@@ -21,7 +20,7 @@ class Configatron::RootStore < BasicObject
21
20
  end
22
21
 
23
22
  def method_missing(name, *args, &block)
24
- store.public_send(name, *args, &block)
23
+ store.__send__(name, *args, &block)
25
24
  end
26
25
 
27
26
  def reset!
@@ -2,7 +2,6 @@ require 'forwardable'
2
2
 
3
3
  class Configatron
4
4
  class Store < BasicObject
5
- include ::Kernel
6
5
  extend ::Forwardable
7
6
 
8
7
  def initialize(root_store, name='configatron', attributes={})
@@ -14,7 +13,7 @@ class Configatron
14
13
  def [](key)
15
14
  val = fetch(key.to_sym) do
16
15
  if @root_store.locked?
17
- raise ::Configatron::UndefinedKeyError.new("Key not found: #{key} (for locked #{self})")
16
+ ::Kernel.raise ::Configatron::UndefinedKeyError.new("Key not found: #{key} (for locked #{self})")
18
17
  end
19
18
  ::Configatron::Store.new(@root_store, "#{@name}.#{key}")
20
19
  end
@@ -23,22 +22,22 @@ class Configatron
23
22
 
24
23
  def store(key, value)
25
24
  if @root_store.locked?
26
- raise ::Configatron::LockedError.new("Cannot set key #{key} for locked #{self}")
25
+ ::Kernel.raise ::Configatron::LockedError.new("Cannot set key #{key} for locked #{self}")
27
26
  end
28
27
  @attributes[key.to_sym] = value
29
28
  end
30
29
 
31
30
  def fetch(key, default_value = nil, &block)
32
31
  val = @attributes[key.to_sym]
33
- if val.nil?
34
- if block_given?
32
+ if val == nil
33
+ if block
35
34
  val = block.call
36
35
  elsif default_value
37
36
  val = default_value
38
37
  end
39
38
  store(key, val)
40
39
  end
41
- if val.is_a?(::Configatron::Proc)
40
+ if ::Configatron::Proc === val
42
41
  val = val.call
43
42
  end
44
43
  return val
@@ -50,7 +49,7 @@ class Configatron
50
49
 
51
50
  def configure_from_hash(hash)
52
51
  hash.each do |key, value|
53
- if value.is_a?(::Hash)
52
+ if ::Hash === value
54
53
  self[key].configure_from_hash(value)
55
54
  else
56
55
  store(key, value)
@@ -65,7 +64,7 @@ class Configatron
65
64
  def inspect
66
65
  f_out = []
67
66
  @attributes.each do |k, v|
68
- if v.is_a?(::Configatron::Store)
67
+ if ::Configatron::Store === v
69
68
  v.inspect.each_line do |line|
70
69
  if line.match(/\n/)
71
70
  line.each_line do |l|
@@ -85,25 +84,23 @@ class Configatron
85
84
  end
86
85
 
87
86
  def method_missing(name, *args, &block)
88
- # Needed to allow 'puts'ing of a configatron.
89
- if name == :to_ary
90
- raise ::NoMethodError.new("Called :to_ary")
91
- end
92
-
93
- # In case of Configatron bugs, prevent method_missing infinite
94
- # loops.
95
- if @method_missing
96
- raise ::NoMethodError.new("Bug in configatron; ended up in method_missing while running: #{name.inspect}")
97
- end
98
- @method_missing = true
99
87
  do_lookup(name, *args, &block)
100
- ensure
101
- @method_missing = false
102
88
  end
103
89
 
104
90
  # Needed for deep_clone to actually clone this object
105
91
  def clone
106
- self.class.new(@root_store, @name, @attributes)
92
+ Store.new(@root_store, @name, @attributes.clone)
93
+ end
94
+
95
+ # So that puts works (it expects the object to respond to to_ary)
96
+ def to_ary
97
+ nil
98
+ end
99
+
100
+ # So that we keep backward-compatibility in case people are using nil? to check
101
+ # configatron settings:
102
+ def nil?
103
+ false
107
104
  end
108
105
 
109
106
  private
@@ -120,7 +117,7 @@ class Configatron
120
117
  if self.has_key?(key)
121
118
  return self[key]
122
119
  else
123
- raise ::Configatron::UndefinedKeyError.new($1)
120
+ ::Kernel.raise ::Configatron::UndefinedKeyError.new($1)
124
121
  end
125
122
  else
126
123
  return self[name]
@@ -1,3 +1,3 @@
1
1
  class Configatron
2
- VERSION = "4.1.0"
2
+ VERSION = "4.1.1"
3
3
  end
@@ -3,5 +3,5 @@
3
3
  # Example:
4
4
  # configatron.emails.welcome.subject = 'Welcome!'
5
5
  # configatron.emails.sales_reciept.subject = 'Thanks for your order'
6
- #
7
- # configatron.file.storage = :s3
6
+ #
7
+ # configatron.file.storage = :s3
@@ -1,4 +1,4 @@
1
1
  # Override your default settings for the Development environment here.
2
- #
2
+ #
3
3
  # Example:
4
- # configatron.file.storage = :local
4
+ # configatron.file.storage = :local
@@ -1,4 +1,4 @@
1
1
  # Override your default settings for the Production environment here.
2
- #
2
+ #
3
3
  # Example:
4
- # configatron.file.storage = :s3
4
+ # configatron.file.storage = :s3
@@ -1,4 +1,4 @@
1
1
  # Override your default settings for the Test environment here.
2
- #
2
+ #
3
3
  # Example:
4
- # configatron.file.storage = :local
4
+ # configatron.file.storage = :local
@@ -1,4 +1,2 @@
1
1
  require 'configatron'
2
- require 'configatron/integrations/rails'
3
-
4
2
  Configatron::Integrations::Rails.init
@@ -51,15 +51,19 @@ class Critic::Functional::ConfigatronTest < Critic::Functional::Test
51
51
  end
52
52
 
53
53
  it 'raises an error when accessing non-existing values' do
54
- refute_nil(@kernel.a)
55
- refute_nil(@kernel.a.b)
56
- refute_nil(@kernel.a.b.c)
54
+ assert @kernel.a != nil
55
+ assert @kernel.a.b != nil
56
+ assert @kernel.a.b.c != nil
57
57
  assert_equal('DD', @kernel.a.b.c.d)
58
58
  assert_raises(Configatron::UndefinedKeyError) do
59
59
  @kernel.unknown
60
60
  end
61
61
  end
62
62
 
63
+ it 'responds to nil? for backward compatibility' do
64
+ refute_nil @kernel.a
65
+ end
66
+
63
67
  it 'raises an error when trying to set a non-existing key' do
64
68
  assert_raises(Configatron::LockedError) do
65
69
  @kernel.unknown = 'known'
@@ -0,0 +1,18 @@
1
+ require_relative '_lib'
2
+
3
+ class Critic::Functional::DelayedTest < Critic::Functional::Test
4
+ before do
5
+ @kernel = Configatron::RootStore.new
6
+ end
7
+
8
+ describe 'delayed' do
9
+ before do
10
+ @kernel.a = Configatron::Delayed.new { @kernel.b }
11
+ @kernel.b = "expected"
12
+ end
13
+
14
+ it 'works independent of the order' do
15
+ assert_equal('expected', @kernel.a)
16
+ end
17
+ end
18
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configatron
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-17 00:00:00.000000000 Z
12
+ date: 2014-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -116,6 +116,7 @@ files:
116
116
  - test/functional/_lib.rb
117
117
  - test/functional/_lib/scripts/core.rb
118
118
  - test/functional/configatron.rb
119
+ - test/functional/delayed.rb
119
120
  - test/functional/loading.rb
120
121
  - test/functional/minitest.rb
121
122
  - test/unit/_lib.rb
@@ -137,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
138
  version: '0'
138
139
  segments:
139
140
  - 0
140
- hash: 201983176826574058
141
+ hash: 2777108850332874749
141
142
  required_rubygems_version: !ruby/object:Gem::Requirement
142
143
  none: false
143
144
  requirements:
@@ -146,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
147
  version: '0'
147
148
  segments:
148
149
  - 0
149
- hash: 201983176826574058
150
+ hash: 2777108850332874749
150
151
  requirements: []
151
152
  rubyforge_project:
152
153
  rubygems_version: 1.8.25
@@ -158,6 +159,7 @@ test_files:
158
159
  - test/functional/_lib.rb
159
160
  - test/functional/_lib/scripts/core.rb
160
161
  - test/functional/configatron.rb
162
+ - test/functional/delayed.rb
161
163
  - test/functional/loading.rb
162
164
  - test/functional/minitest.rb
163
165
  - test/unit/_lib.rb