hashr 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hashr (0.0.5)
4
+ hashr (0.0.6)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
@@ -1,3 +1,5 @@
1
+ require 'hashr/core_ext/ruby/hash'
2
+
1
3
  class Hashr < Hash
2
4
  autoload :EnvDefaults, 'hashr/env_defaults'
3
5
 
@@ -7,7 +9,7 @@ class Hashr < Hash
7
9
  attr_accessor :raise_missing_keys
8
10
 
9
11
  def define(definition)
10
- @definition = definition
12
+ @definition = definition.deep_symbolize_keys
11
13
  end
12
14
 
13
15
  def definition
@@ -15,13 +17,12 @@ class Hashr < Hash
15
17
  end
16
18
  end
17
19
 
18
- def initialize(data = {})
19
- include_modules(data.delete(:_include)) if data
20
- replace(deep_hasherize(deep_merge(self.class.definition, data)))
20
+ def initialize(data = {}, definition = self.class.definition)
21
+ replace(deep_hashrize(definition.deep_merge(data.deep_symbolize_keys)))
21
22
  end
22
23
 
23
24
  def []=(key, value)
24
- super(key, value.is_a?(Hash) ? self.class.new(value) : value)
25
+ super(key, value.is_a?(Hash) ? self.class.new(value, {}) : value)
25
26
  end
26
27
 
27
28
  def respond_to?(name)
@@ -40,24 +41,23 @@ class Hashr < Hash
40
41
  end
41
42
  end
42
43
 
43
- protected
44
-
45
- def include_modules(modules)
46
- Array(modules).each { |mod| meta_class.send(:include, mod) } if modules
47
- end
44
+ def include_modules(modules)
45
+ Array(modules).each { |mod| meta_class.send(:include, mod) } if modules
46
+ end
48
47
 
49
- def meta_class
50
- class << self; self end
51
- end
48
+ def meta_class
49
+ class << self; self end
50
+ end
52
51
 
53
- def deep_merge(left, right)
54
- merger = proc { |key, v1, v2| v1.is_a?(Hash) && v2.is_a?(Hash) ? self.class.new(v1.merge(v2, &merger)) : v2 }
55
- left.merge(right || {}, &merger)
56
- end
52
+ protected
57
53
 
58
- def deep_hasherize(hash)
54
+ def deep_hashrize(hash)
59
55
  hash.inject(TEMPLATE.dup) do |result, (key, value)|
60
- result[key.to_sym] = value.is_a?(Hash) ? deep_hasherize(value) : value
56
+ if key.to_sym == :_include
57
+ result.include_modules(value)
58
+ else
59
+ result.store(key.to_sym, value.is_a?(Hash) ? deep_hashrize(value) : value)
60
+ end
61
61
  result
62
62
  end
63
63
  end
@@ -0,0 +1,28 @@
1
+ class Hash
2
+ def slice(*keep_keys)
3
+ h = {}
4
+ keep_keys.each { |key| h[key] = fetch(key) }
5
+ h
6
+ end unless Hash.method_defined?(:slice)
7
+
8
+ def except(*less_keys)
9
+ slice(*keys - less_keys)
10
+ end unless Hash.method_defined?(:except)
11
+
12
+ def deep_symbolize_keys
13
+ inject({}) { |result, (key, value)|
14
+ value = value.deep_symbolize_keys if value.is_a?(Hash)
15
+ result[(key.to_sym rescue key) || key] = value
16
+ result
17
+ }
18
+ end unless Hash.method_defined?(:deep_symbolize_keys)
19
+
20
+ # deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
21
+ MERGER = proc do |key, v1, v2|
22
+ Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2
23
+ end
24
+
25
+ def deep_merge(other)
26
+ merge(other, &MERGER)
27
+ end unless Hash.method_defined?(:deep_merge)
28
+ end
@@ -1,3 +1,3 @@
1
1
  class Hashr < Hash
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
@@ -41,6 +41,24 @@ class HashrTest < Test::Unit::TestCase
41
41
  assert_equal false, Hashr.new({ :foo => { :bar => 'bar' } }).foo.baz?
42
42
  end
43
43
 
44
+ test 'mixing symbol and string keys in defaults and data' do
45
+ Symbolized = Class.new(Hashr) { define :foo => 'foo' }
46
+ Stringified = Class.new(Hashr) { define 'foo' => 'foo' }
47
+ NoDefault = Class.new(Hashr)
48
+
49
+ assert_equal 'foo', Symbolized.new.foo
50
+ assert_equal 'foo', Stringified.new.foo
51
+ assert_nil NoDefault.new.foo
52
+
53
+ assert_equal 'foo', Symbolized.new(:foo => 'foo').foo
54
+ assert_equal 'foo', Stringified.new(:foo => 'foo').foo
55
+ assert_equal 'foo', NoDefault.new(:foo => 'foo').foo
56
+
57
+ assert_equal 'foo', Symbolized.new('foo' => 'foo').foo
58
+ assert_equal 'foo', Stringified.new('foo' => 'foo').foo
59
+ assert_equal 'foo', NoDefault.new('foo' => 'foo').foo
60
+ end
61
+
44
62
  test 'method assignment works' do
45
63
  hashr = Hashr.new
46
64
  hashr.foo = 'foo'
@@ -94,6 +112,14 @@ class HashrTest < Test::Unit::TestCase
94
112
  end
95
113
 
96
114
  test 'a key :_include includes the given modules' do
115
+ klass = Class.new(Hashr) do
116
+ define :foo => { :_include => Module.new { def helper; 'helper'; end } }
117
+ end
118
+ hashr = klass.new(:foo => { 'helper' => 'foo' })
119
+ assert_equal 'helper', klass.new(:foo => { 'helper' => 'foo' }).foo.helper
120
+ end
121
+
122
+ test 'a key :_include includes the given modules (using defaults)' do
97
123
  klass = Class.new(Hashr) do
98
124
  define :foo => { :_include => Module.new { def helper; 'helper'; end } }
99
125
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashr
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sven Fuchs
@@ -57,6 +57,7 @@ extensions: []
57
57
  extra_rdoc_files: []
58
58
 
59
59
  files:
60
+ - lib/hashr/core_ext/ruby/hash.rb
60
61
  - lib/hashr/env_defaults.rb
61
62
  - lib/hashr/version.rb
62
63
  - lib/hashr.rb