casted_hash 0.0.2 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 901edabae24fed434f5c0a5c6e83845831ea0163
4
- data.tar.gz: 9cc31472995f046c5bbecc736a952a2fdf7b26a4
3
+ metadata.gz: 5fbb548f016a133c4d10ff789086c7402e956da1
4
+ data.tar.gz: a77641ba09b64407763ce8e547d252dab608b763
5
5
  SHA512:
6
- metadata.gz: b6c011883db3dc8da0212b322be8657d6d4b7c89f3833e955d9a85a16fe3d1cc520f70f7e0b4f8703b53e043409132b600df81d0a2a479cc2cd2034d959393b4
7
- data.tar.gz: 63d783be719a14ad5317be58abaa0250850be1d7ddb8a4de5e0e7c8227bde4b7c030651727d6f657ee9a6090e9ea59f6db3a22ae2a7a2843e3095dae130b1bc3
6
+ metadata.gz: 6a36b6e3d4f058eaa52f8c422aacb5f5a82c8a4a8b95dc3df358536790f2de4accf98a74eec20eb2bdcaac65fb9bd241eb3ff3e6fda037122548fbeb24c059b2
7
+ data.tar.gz: be2f8f407d9cbf209ba84761ca849224c3ef8f124a4ae821ff72dc33b9b29d464a59cf31b87875c15fb5d6d4ba674480f676b11909316ab0d77878c073dde6db
@@ -2,10 +2,11 @@ class CastedHash
2
2
  class Value
3
3
  include Equalizer.new(:value)
4
4
  attr_reader :value
5
+ attr_accessor :casted_hash
5
6
 
6
- def initialize(value, cast_proc)
7
+ def initialize(value, casted_hash)
7
8
  @value = value
8
- @cast_proc = cast_proc
9
+ @casted_hash = casted_hash
9
10
  end
10
11
 
11
12
  def casted_value
@@ -20,7 +21,7 @@ class CastedHash
20
21
  def cast!
21
22
  return if casted?
22
23
 
23
- @value = @cast_proc.call(value)
24
+ @value = casted_hash.cast_proc.call(value)
24
25
  @casted = true
25
26
  end
26
27
  end
@@ -1,3 +1,3 @@
1
1
  class CastedHash
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/casted_hash.rb CHANGED
@@ -9,11 +9,21 @@ class CastedHash
9
9
  attr_reader :cast_proc
10
10
 
11
11
  def_delegators :@hash, *[:keys, :inject, :key?, :include?]
12
- def_delegators :casted_hash, *[:collect]
12
+ def_delegators :casted_hash, *[:collect, :reject]
13
+
14
+ def initialize(constructor = {}, cast_proc = nil)
15
+ raise ArgumentError, "`cast_proc` required" unless cast_proc
13
16
 
14
- def initialize(constructor = {}, cast_proc = lambda { |x| x })
15
17
  @cast_proc = cast_proc
16
- @hash = HashWithIndifferentAccess.new(pack_hash(constructor))
18
+
19
+ if constructor.is_a?(Hash)
20
+ @hash = HashWithIndifferentAccess.new
21
+ update(constructor)
22
+ elsif constructor.is_a?(CastedHash)
23
+ @hash = constructor.pack_hash(self)
24
+ else
25
+ raise ArgumentError
26
+ end
17
27
  end
18
28
 
19
29
  def each
@@ -55,14 +65,24 @@ class CastedHash
55
65
  @hash
56
66
  end
57
67
 
58
- def merge(other)
59
- other = other.to_hash
60
- self.class.new(@hash.merge(other), cast_proc)
68
+ def pack_hash(casted_hash)
69
+ @hash.inject(HashWithIndifferentAccess.new) do |hash, (key, value)|
70
+ hash.merge key => pack(value, casted_hash)
71
+ end
61
72
  end
62
73
 
63
- def merge!(other)
64
- other = pack_hash(other)
65
- @hash.merge!(other)
74
+ def update(other_hash)
75
+ if other_hash.is_a? CastedHash
76
+ @hash.update other_hash.pack_hash(self)
77
+ else
78
+ other_hash.each_pair { |key, value| store(key, value) }
79
+ end
80
+
81
+ self
82
+ end
83
+
84
+ def merge(other)
85
+ self.dup.update other
66
86
  end
67
87
 
68
88
  def casted?(key)
@@ -82,6 +102,10 @@ class CastedHash
82
102
  end
83
103
  end
84
104
 
105
+ def dup
106
+ self.class.new(self, @cast_proc)
107
+ end
108
+
85
109
  private
86
110
 
87
111
  def raw
@@ -94,17 +118,13 @@ private
94
118
  end
95
119
  end
96
120
 
97
- def pack(value)
121
+ def pack(value, casted_hash = self)
98
122
  if value.is_a?(Value)
123
+ value.casted_hash = casted_hash
99
124
  value
100
125
  else
101
- Value.new(value, cast_proc)
126
+ Value.new(value, casted_hash)
102
127
  end
103
128
  end
104
129
 
105
- def pack_hash(hash)
106
- hash.inject({}) do |hash, (key, value)|
107
- hash.merge key => pack(value)
108
- end if hash
109
- end
110
130
  end
@@ -44,7 +44,7 @@ class TestCastedHash < Minitest::Test
44
44
  end
45
45
 
46
46
  it "should inspect casted values" do
47
- hash = CastedHash.new(nil, lambda { |x| "foobar" })
47
+ hash = CastedHash.new({}, lambda { |x| "foobar" })
48
48
 
49
49
  assert_equal("#<CastedHash hash={}>", hash.inspect)
50
50
 
@@ -87,15 +87,33 @@ class TestCastedHash < Minitest::Test
87
87
  assert_equal 12, hash[:b]
88
88
  end
89
89
 
90
- it "should merge! values" do
91
- hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
92
- assert_equal 11, hash[:a]
93
- assert_equal 12, hash[:b]
94
-
95
- hash.merge!({:a => 3})
90
+ it "should take over scope when merging two casted hashes" do
91
+ hash1 = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
92
+ hash2 = CastedHash.new({:c => 3, :d => 4}, lambda {|x| x + 100 })
96
93
 
97
- assert_equal 13, hash[:a]
98
- assert_equal 12, hash[:b]
94
+ assert_equal 11, hash1[:a]
95
+ assert_equal 12, hash1[:b]
96
+ assert hash1.casted?(:a)
97
+ assert hash1.casted?(:b)
98
+
99
+ cast_proc1_object_id = hash1.cast_proc.object_id
100
+ assert_equal [hash1.object_id], hash1.send(:raw).values.map{|v|v.casted_hash.object_id}.uniq
101
+
102
+ hash3 = hash1.merge hash2
103
+
104
+ assert_equal [hash3.object_id], hash3.send(:raw).values.map{|v|v.casted_hash.object_id}.uniq
105
+ assert_equal hash3.cast_proc.object_id, cast_proc1_object_id
106
+
107
+ assert_equal ["a", "b", "c", "d"], hash3.keys
108
+ assert hash3.casted?(:a)
109
+ assert hash3.casted?(:b)
110
+ assert !hash3.casted?(:c)
111
+ assert !hash3.casted?(:d)
112
+
113
+ assert_equal 11, hash3[:a]
114
+ assert_equal 12, hash3[:b]
115
+ assert_equal 13, hash3[:c]
116
+ assert_equal 14, hash3[:d]
99
117
  end
100
118
 
101
119
  it "should not cast all values when merging hashes" do
@@ -106,12 +124,6 @@ class TestCastedHash < Minitest::Test
106
124
  assert !hash.casted?(:b)
107
125
  assert !hash.casted?(:c)
108
126
 
109
- hash.merge! :c => 3
110
-
111
- assert !hash.casted?(:a)
112
- assert !hash.casted?(:b)
113
- assert !hash.casted?(:c)
114
-
115
127
  other_hash = CastedHash.new({:c => 1, :d => 2}, lambda {|x| x + 10 })
116
128
  hash = hash.merge other_hash
117
129
 
@@ -120,15 +132,6 @@ class TestCastedHash < Minitest::Test
120
132
  assert !hash.casted?(:c)
121
133
  assert !other_hash.casted?(:c)
122
134
  assert !other_hash.casted?(:d)
123
-
124
- other_hash = CastedHash.new({:c => 1, :d => 2}, lambda {|x| x + 10 })
125
- hash.merge! other_hash
126
-
127
- assert !hash.casted?(:a)
128
- assert !hash.casted?(:b)
129
- assert !hash.casted?(:c)
130
- assert !other_hash.casted?(:c)
131
- assert !other_hash.casted?(:d)
132
135
  end
133
136
 
134
137
  it "should define a hash method" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: casted_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephan Kaag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-31 00:00:00.000000000 Z
11
+ date: 2013-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: equalizer