casted_hash 0.1.4 → 0.2.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 +4 -4
- data/casted_hash.gemspec +2 -4
- data/lib/casted_hash.rb +77 -77
- data/test/test_casted_hash.rb +153 -186
- metadata +14 -44
- data/lib/casted_hash/value.rb +0 -33
- data/lib/casted_hash/version.rb +0 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 80a47e0dbe45026edc63a50e69adf59090ffd638
|
|
4
|
+
data.tar.gz: 973fc8ba7cadd92869cb0667b8875c3ef500efd2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1f0ff29181122f15a57bcadc791402b0010db1c186c0b44dca5dadee33276f49392712cd92d43792a7bf9b4ec2e593a2767f3ae6775e25859eb39d5e0f95b0f7
|
|
7
|
+
data.tar.gz: 40a7606d898ef57a6671bc10a3af21f4b3a87a4fc5726ea0bb82f892a35d4761e814f6b8a5e62f4dbf9a0df38eacd58a1e3bf0662dd0e66931270e8e31fad0f4
|
data/casted_hash.gemspec
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# coding: utf-8
|
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require 'casted_hash
|
|
4
|
+
require 'casted_hash'
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "casted_hash"
|
|
@@ -14,10 +14,8 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
15
15
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
16
16
|
spec.require_paths = ["lib"]
|
|
17
|
-
spec.add_dependency "equalizer", ">= 0.0.7"
|
|
18
|
-
spec.add_dependency "activesupport"
|
|
19
17
|
|
|
20
|
-
spec.add_development_dependency "bundler", "
|
|
18
|
+
spec.add_development_dependency "bundler", ">= 1.3"
|
|
21
19
|
spec.add_development_dependency "rake"
|
|
22
20
|
spec.add_development_dependency "minitest", "~> 5"
|
|
23
21
|
spec.add_development_dependency "coveralls"
|
data/lib/casted_hash.rb
CHANGED
|
@@ -1,133 +1,133 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require "casted_hash/value"
|
|
4
|
-
require "active_support/hash_with_indifferent_access"
|
|
5
|
-
|
|
6
|
-
class CastedHash
|
|
7
|
-
include Equalizer.new(:raw, :cast_proc)
|
|
8
|
-
extend Forwardable
|
|
9
|
-
attr_reader :cast_proc
|
|
10
|
-
|
|
11
|
-
def_delegators :@hash, *[:keys, :inject, :key?, :include?, :empty?, :any?]
|
|
12
|
-
def_delegators :casted_hash, *[:collect, :reject]
|
|
1
|
+
class CastedHash < Hash
|
|
2
|
+
VERSION = "0.2.0"
|
|
13
3
|
|
|
14
4
|
def initialize(constructor = {}, cast_proc = nil)
|
|
15
5
|
raise ArgumentError, "`cast_proc` required" unless cast_proc
|
|
16
6
|
|
|
17
7
|
@cast_proc = cast_proc
|
|
18
8
|
|
|
19
|
-
if constructor.is_a?(
|
|
20
|
-
|
|
9
|
+
if constructor.is_a?(CastedHash)
|
|
10
|
+
super()
|
|
11
|
+
@casted_keys = constructor.instance_variable_get(:@casted_keys)
|
|
12
|
+
regular_update(constructor)
|
|
13
|
+
elsif constructor.is_a?(Hash)
|
|
14
|
+
@casted_keys = []
|
|
15
|
+
super()
|
|
21
16
|
update(constructor)
|
|
22
|
-
elsif constructor.is_a?(CastedHash)
|
|
23
|
-
@hash = constructor.pack_hash(self)
|
|
24
17
|
else
|
|
25
|
-
|
|
18
|
+
@casted_keys = []
|
|
19
|
+
super(constructor)
|
|
26
20
|
end
|
|
27
21
|
end
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
@hash.each do |key, value|
|
|
31
|
-
yield key, value.casted_value
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
alias_method :each_pair, :each
|
|
23
|
+
alias_method :regular_reader, :[] unless method_defined?(:regular_reader)
|
|
35
24
|
|
|
36
|
-
def
|
|
37
|
-
|
|
25
|
+
def [](key)
|
|
26
|
+
cast! key
|
|
38
27
|
end
|
|
39
28
|
|
|
40
|
-
def fetch(key, *
|
|
41
|
-
|
|
29
|
+
def fetch(key, *extras)
|
|
30
|
+
value = cast!(key)
|
|
42
31
|
|
|
43
|
-
if
|
|
44
|
-
|
|
32
|
+
if value.nil?
|
|
33
|
+
super(convert_key(key), *extras)
|
|
45
34
|
else
|
|
46
|
-
|
|
35
|
+
value
|
|
47
36
|
end
|
|
48
37
|
end
|
|
49
38
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
val.casted_value unless val.nil?
|
|
53
|
-
end
|
|
39
|
+
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
|
40
|
+
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
|
54
41
|
|
|
55
42
|
def []=(key, value)
|
|
56
|
-
@
|
|
43
|
+
@casted_keys.delete key.to_s
|
|
44
|
+
regular_writer(convert_key(key), value)
|
|
57
45
|
end
|
|
58
|
-
alias_method :store, :[]=
|
|
59
46
|
|
|
60
|
-
|
|
61
|
-
@hash.delete(key)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def to_hash
|
|
65
|
-
@hash
|
|
66
|
-
end
|
|
47
|
+
alias_method :store, :[]=
|
|
67
48
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
hash.merge key => pack(value, casted_hash)
|
|
71
|
-
end
|
|
49
|
+
def merge(hash)
|
|
50
|
+
self.dup.update(hash)
|
|
72
51
|
end
|
|
73
52
|
|
|
74
53
|
def update(other_hash)
|
|
75
54
|
return self if other_hash.empty?
|
|
76
55
|
|
|
77
56
|
if other_hash.is_a? CastedHash
|
|
78
|
-
@
|
|
57
|
+
other_hash.keys.each{|key| @casted_keys.delete key}
|
|
58
|
+
super(other_hash)
|
|
79
59
|
else
|
|
80
|
-
other_hash.each_pair { |key, value|
|
|
60
|
+
other_hash.each_pair { |key, value| self[key] = value }
|
|
61
|
+
self
|
|
81
62
|
end
|
|
82
|
-
|
|
83
|
-
self
|
|
84
63
|
end
|
|
64
|
+
|
|
85
65
|
alias_method :merge!, :update
|
|
86
66
|
|
|
87
|
-
def
|
|
88
|
-
|
|
67
|
+
def key?(key)
|
|
68
|
+
super(convert_key(key))
|
|
89
69
|
end
|
|
90
70
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
71
|
+
alias_method :include?, :key?
|
|
72
|
+
alias_method :has_key?, :key?
|
|
73
|
+
alias_method :member?, :key?
|
|
74
|
+
|
|
75
|
+
def values_at(*indices)
|
|
76
|
+
indices.collect {|key| self[convert_key(key)]}
|
|
94
77
|
end
|
|
95
78
|
|
|
96
|
-
def
|
|
97
|
-
|
|
79
|
+
def dup
|
|
80
|
+
self.class.new(self, @cast_proc)
|
|
98
81
|
end
|
|
99
82
|
|
|
100
|
-
def
|
|
83
|
+
def delete(key)
|
|
84
|
+
@casted_keys.delete key.to_s
|
|
85
|
+
super(convert_key(key))
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def values
|
|
101
89
|
cast_all!
|
|
90
|
+
super
|
|
91
|
+
end
|
|
102
92
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
93
|
+
def each
|
|
94
|
+
cast_all!
|
|
95
|
+
super
|
|
106
96
|
end
|
|
107
97
|
|
|
108
|
-
def
|
|
109
|
-
|
|
98
|
+
def casted_hash
|
|
99
|
+
cast_all!
|
|
100
|
+
self
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def casted?(key)
|
|
104
|
+
@casted_keys.include?(key.to_s)
|
|
110
105
|
end
|
|
111
106
|
|
|
112
|
-
|
|
107
|
+
protected
|
|
108
|
+
|
|
109
|
+
def cast!(key)
|
|
110
|
+
return unless key?(key)
|
|
111
|
+
return regular_reader(convert_key(key)) if casted?(key)
|
|
112
|
+
@casted_keys << key.to_s
|
|
113
|
+
|
|
114
|
+
value = if @cast_proc.arity == 1
|
|
115
|
+
@cast_proc.call regular_reader(convert_key(key))
|
|
116
|
+
elsif @cast_proc.arity == 2
|
|
117
|
+
@cast_proc.call key, regular_reader(convert_key(key))
|
|
118
|
+
else
|
|
119
|
+
@cast_proc.call
|
|
120
|
+
end
|
|
113
121
|
|
|
114
|
-
|
|
115
|
-
@hash
|
|
122
|
+
regular_writer(convert_key(key), value)
|
|
116
123
|
end
|
|
117
124
|
|
|
118
125
|
def cast_all!
|
|
119
|
-
|
|
120
|
-
value.cast!
|
|
121
|
-
end
|
|
126
|
+
keys.each{|key| cast! key}
|
|
122
127
|
end
|
|
123
128
|
|
|
124
|
-
def
|
|
125
|
-
|
|
126
|
-
value.casted_hash = casted_hash
|
|
127
|
-
value
|
|
128
|
-
else
|
|
129
|
-
Value.new(value, casted_hash)
|
|
130
|
-
end
|
|
129
|
+
def convert_key(key)
|
|
130
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
|
131
131
|
end
|
|
132
132
|
|
|
133
133
|
end
|
data/test/test_casted_hash.rb
CHANGED
|
@@ -1,244 +1,211 @@
|
|
|
1
1
|
require 'helper'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
describe CastedHash do
|
|
3
|
+
describe CastedHash do
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
it "is able to define a cast method" do
|
|
6
|
+
hash = CastedHash.new({:foo => 1}, lambda { |x| x.to_s })
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
hash[:bar] = 1
|
|
9
|
+
assert_equal "1", hash[:bar]
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
hash[:bar] = 2
|
|
12
|
+
assert_equal "2", hash[:bar]
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
it "should not loop when refering to itself" do
|
|
20
|
-
@hash = CastedHash.new({:a => 1}, lambda {|x| @hash[:a] + 1 })
|
|
21
|
-
exception = assert_raises(SystemStackError) do
|
|
22
|
-
@hash[:a]
|
|
23
|
-
end
|
|
24
|
-
assert_equal "Cannot cast value that is currently being cast", exception.message
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "should cast when expected" do
|
|
28
|
-
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
29
|
-
assert !hash.casted?(:a)
|
|
30
|
-
assert !hash.casted?(:b)
|
|
14
|
+
hash.store :bar, 3
|
|
15
|
+
assert_equal "3", hash[:bar]
|
|
16
|
+
end
|
|
31
17
|
|
|
32
|
-
|
|
18
|
+
it "does not loop when refering to itself" do
|
|
19
|
+
@hash = CastedHash.new({:a => 1}, lambda {|x| @hash[:a] + 1 })
|
|
20
|
+
assert_equal 2, @hash[:a]
|
|
21
|
+
end
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
23
|
+
it "casts when expected" do
|
|
24
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
25
|
+
assert !hash.casted?(:a)
|
|
26
|
+
assert !hash.casted?(:b)
|
|
37
27
|
|
|
38
|
-
|
|
39
|
-
hash = CastedHash.new({}, lambda {})
|
|
40
|
-
assert hash.empty?
|
|
41
|
-
assert !hash.any?
|
|
28
|
+
assert_equal 11, hash[:a]
|
|
42
29
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
end
|
|
30
|
+
assert hash.casted?(:a)
|
|
31
|
+
assert !hash.casted?(:b)
|
|
32
|
+
end
|
|
47
33
|
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
it "responds to any? and empty?" do
|
|
35
|
+
hash = CastedHash.new({}, lambda {})
|
|
36
|
+
assert hash.empty?
|
|
37
|
+
assert !hash.any?
|
|
50
38
|
|
|
51
|
-
|
|
52
|
-
|
|
39
|
+
hash = CastedHash.new({:foo => "bar"}, lambda {})
|
|
40
|
+
assert !hash.empty?
|
|
41
|
+
assert hash.any?
|
|
42
|
+
end
|
|
53
43
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
assert_equal 124, hash[:bar]
|
|
57
|
-
end
|
|
44
|
+
it "only casts once" do
|
|
45
|
+
hash = CastedHash.new({:foo => 1}, lambda { |x| x + 1 })
|
|
58
46
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
assert_equal [10, 100, 1000], hash.values
|
|
62
|
-
end
|
|
47
|
+
assert_equal 2, hash[:foo]
|
|
48
|
+
assert_equal 2, hash[:foo]
|
|
63
49
|
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
hash[:bar] = 123
|
|
51
|
+
assert_equal 124, hash[:bar]
|
|
52
|
+
assert_equal 124, hash[:bar]
|
|
53
|
+
end
|
|
66
54
|
|
|
67
|
-
|
|
55
|
+
it "is able to fetch all casted values" do
|
|
56
|
+
hash = CastedHash.new({:a => 1, :b => 10, :c => 100}, lambda { |x| x * 10 })
|
|
57
|
+
assert_equal [10, 100, 1000], hash.values
|
|
58
|
+
end
|
|
68
59
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
assert_equal("#<CastedHash hash={\"bar\"=>\"foobar\"}>", hash.inspect)
|
|
60
|
+
it "loops through casted values" do
|
|
61
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda { |x| "processed: #{x}" })
|
|
62
|
+
map = []
|
|
73
63
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
assert_equal("foobar", hash[:foo])
|
|
77
|
-
assert_equal("#<CastedHash hash={\"foo\"=>\"foobar\"}>", hash.inspect)
|
|
64
|
+
hash.each do |key, value|
|
|
65
|
+
map << value
|
|
78
66
|
end
|
|
79
67
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
map = []
|
|
83
|
-
|
|
84
|
-
hash.each do |key, value|
|
|
85
|
-
map << value
|
|
86
|
-
end
|
|
68
|
+
assert_equal ["processed: 1", "processed: 2"], map
|
|
69
|
+
end
|
|
87
70
|
|
|
88
|
-
|
|
89
|
-
|
|
71
|
+
it "deletes values" do
|
|
72
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
73
|
+
hash.delete(:b)
|
|
74
|
+
assert_equal({"a" => 11}, hash.casted_hash)
|
|
75
|
+
end
|
|
90
76
|
|
|
91
|
-
|
|
77
|
+
describe "merge" do
|
|
78
|
+
it "merges values" do
|
|
92
79
|
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
93
|
-
hash
|
|
94
|
-
assert_equal
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
describe "merge" do
|
|
98
|
-
it "should merge values" do
|
|
99
|
-
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
100
|
-
assert_equal 11, hash[:a]
|
|
101
|
-
assert_equal 12, hash[:b]
|
|
102
|
-
|
|
103
|
-
hash = hash.merge({:a => 3})
|
|
80
|
+
assert_equal 11, hash[:a]
|
|
81
|
+
assert_equal 12, hash[:b]
|
|
104
82
|
|
|
105
|
-
|
|
106
|
-
assert_equal 12, hash[:b]
|
|
83
|
+
hash = hash.merge({:a => 3})
|
|
107
84
|
|
|
108
|
-
|
|
109
|
-
|
|
85
|
+
assert_equal 13, hash[:a]
|
|
86
|
+
assert_equal 12, hash[:b]
|
|
110
87
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
hash2 = CastedHash.new({:c => 3, :d => 4}, lambda {|x| x + 100 })
|
|
114
|
-
|
|
115
|
-
assert_equal 11, hash1[:a]
|
|
116
|
-
assert_equal 12, hash1[:b]
|
|
117
|
-
assert hash1.casted?(:a)
|
|
118
|
-
assert hash1.casted?(:b)
|
|
119
|
-
|
|
120
|
-
cast_proc1_object_id = hash1.cast_proc.object_id
|
|
121
|
-
assert_equal [hash1.object_id], hash1.send(:raw).values.map{|v|v.casted_hash.object_id}.uniq
|
|
122
|
-
|
|
123
|
-
hash3 = hash1.merge hash2
|
|
88
|
+
assert_equal hash, hash.merge({})
|
|
89
|
+
end
|
|
124
90
|
|
|
125
|
-
|
|
126
|
-
|
|
91
|
+
it "leaves original hash alone" do
|
|
92
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
93
|
+
new_hash = hash.merge({:c => 3})
|
|
127
94
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
assert !hash3.casted?(:c)
|
|
132
|
-
assert !hash3.casted?(:d)
|
|
95
|
+
assert_equal ['a', 'b', 'c'], new_hash.keys
|
|
96
|
+
assert_equal ['a', 'b'], hash.keys
|
|
97
|
+
end
|
|
133
98
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
assert_equal 14, hash3[:d]
|
|
138
|
-
end
|
|
99
|
+
it "takes over scope when merging two casted hashes" do
|
|
100
|
+
hash1 = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
101
|
+
hash2 = CastedHash.new({:a => 2, :c => 3, :d => 4}, lambda {|x| x + 100 })
|
|
139
102
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
103
|
+
assert_equal 11, hash1[:a]
|
|
104
|
+
assert_equal 12, hash1[:b]
|
|
105
|
+
assert_equal 104, hash2[:d]
|
|
106
|
+
assert hash1.casted?(:a)
|
|
107
|
+
assert hash1.casted?(:b)
|
|
143
108
|
|
|
144
|
-
|
|
145
|
-
assert !hash.casted?(:b)
|
|
146
|
-
assert !hash.casted?(:c)
|
|
109
|
+
hash3 = hash1.merge hash2
|
|
147
110
|
|
|
148
|
-
|
|
149
|
-
|
|
111
|
+
assert_equal ["a", "b", "c", "d"], hash3.keys
|
|
112
|
+
assert !hash3.casted?(:a)
|
|
113
|
+
assert hash3.casted?(:b)
|
|
114
|
+
assert !hash3.casted?(:c)
|
|
115
|
+
assert !hash3.casted?(:d)
|
|
150
116
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
assert !other_hash.casted?(:d)
|
|
156
|
-
end
|
|
117
|
+
assert_equal 12, hash3[:a]
|
|
118
|
+
assert_equal 12, hash3[:b]
|
|
119
|
+
assert_equal 13, hash3[:c]
|
|
120
|
+
assert_equal 114, hash3[:d] # casted twice
|
|
157
121
|
end
|
|
158
122
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
assert_equal 11, hash[:a]
|
|
163
|
-
assert_equal 12, hash[:b]
|
|
123
|
+
it "does not cast all values when merging hashes" do
|
|
124
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
125
|
+
hash = hash.merge :c => 3
|
|
164
126
|
|
|
165
|
-
|
|
127
|
+
assert !hash.casted?(:a)
|
|
128
|
+
assert !hash.casted?(:b)
|
|
129
|
+
assert !hash.casted?(:c)
|
|
166
130
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
end
|
|
131
|
+
other_hash = CastedHash.new({:c => 1, :d => 2}, lambda {|x| x + 10 })
|
|
132
|
+
hash = hash.merge other_hash
|
|
170
133
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
134
|
+
assert !hash.casted?(:a)
|
|
135
|
+
assert !hash.casted?(:b)
|
|
136
|
+
assert !hash.casted?(:c)
|
|
137
|
+
assert !other_hash.casted?(:c)
|
|
138
|
+
assert !other_hash.casted?(:d)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
174
141
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
142
|
+
describe "merge!" do
|
|
143
|
+
it "merge!s values" do
|
|
144
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
145
|
+
assert_equal 11, hash[:a]
|
|
146
|
+
assert_equal 12, hash[:b]
|
|
179
147
|
|
|
180
|
-
|
|
181
|
-
assert_equal [hash1.object_id], hash1.send(:raw).values.map{|v|v.casted_hash.object_id}.uniq
|
|
148
|
+
hash.merge!({:a => 3})
|
|
182
149
|
|
|
183
|
-
|
|
150
|
+
assert_equal 13, hash[:a]
|
|
151
|
+
assert_equal 12, hash[:b]
|
|
152
|
+
end
|
|
184
153
|
|
|
185
|
-
|
|
186
|
-
|
|
154
|
+
it "takes over scope when merging two casted hashes" do
|
|
155
|
+
hash1 = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
156
|
+
hash2 = CastedHash.new({:c => 3, :d => 4}, lambda {|x| x + 100 })
|
|
187
157
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
assert !hash1.casted?(:d)
|
|
158
|
+
assert_equal 11, hash1[:a]
|
|
159
|
+
assert_equal 12, hash1[:b]
|
|
160
|
+
assert hash1.casted?(:a)
|
|
161
|
+
assert hash1.casted?(:b)
|
|
193
162
|
|
|
194
|
-
|
|
195
|
-
assert_equal 12, hash1[:b]
|
|
196
|
-
assert_equal 13, hash1[:c]
|
|
197
|
-
assert_equal 14, hash1[:d]
|
|
198
|
-
end
|
|
163
|
+
hash1.merge! hash2
|
|
199
164
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
165
|
+
assert_equal ["a", "b", "c", "d"], hash1.keys
|
|
166
|
+
assert hash1.casted?(:a)
|
|
167
|
+
assert hash1.casted?(:b)
|
|
168
|
+
assert !hash1.casted?(:c)
|
|
169
|
+
assert !hash1.casted?(:d)
|
|
203
170
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
171
|
+
assert_equal 11, hash1[:a]
|
|
172
|
+
assert_equal 12, hash1[:b]
|
|
173
|
+
assert_equal 13, hash1[:c]
|
|
174
|
+
assert_equal 14, hash1[:d]
|
|
175
|
+
end
|
|
207
176
|
|
|
208
|
-
|
|
209
|
-
|
|
177
|
+
it "does not cast all values when merging hashes" do
|
|
178
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 10 })
|
|
179
|
+
hash.merge! :c => 3
|
|
210
180
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
assert !other_hash.casted?(:c)
|
|
215
|
-
assert !other_hash.casted?(:d)
|
|
216
|
-
end
|
|
217
|
-
end
|
|
181
|
+
assert !hash.casted?(:a)
|
|
182
|
+
assert !hash.casted?(:b)
|
|
183
|
+
assert !hash.casted?(:c)
|
|
218
184
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
hash1 = CastedHash.new({:a => 1, :b => 2}, l)
|
|
222
|
-
hash2 = CastedHash.new({:a => 1, :b => 2}, l)
|
|
223
|
-
hash3 = CastedHash.new({:a => 1, :b => 2}, lambda {|x| x + 11 })
|
|
185
|
+
other_hash = CastedHash.new({:c => 1, :d => 2}, lambda {|x| x + 10 })
|
|
186
|
+
hash.merge! other_hash
|
|
224
187
|
|
|
225
|
-
|
|
226
|
-
assert
|
|
188
|
+
assert !hash.casted?(:a)
|
|
189
|
+
assert !hash.casted?(:b)
|
|
190
|
+
assert !hash.casted?(:c)
|
|
191
|
+
assert !other_hash.casted?(:c)
|
|
192
|
+
assert !other_hash.casted?(:d)
|
|
227
193
|
end
|
|
194
|
+
end
|
|
228
195
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
assert_equal ["a", "b"], hash.keys
|
|
196
|
+
it "does not add all requested values" do
|
|
197
|
+
hash = CastedHash.new({:a => 1, :b => 2}, lambda {|x|x + 1})
|
|
198
|
+
assert_equal 2, hash.fetch(:a)
|
|
234
199
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
end
|
|
200
|
+
assert_nil hash[:undefined_key]
|
|
201
|
+
assert_equal ["a", "b"], hash.keys
|
|
238
202
|
|
|
239
|
-
|
|
240
|
-
|
|
203
|
+
assert_raises(KeyError) do
|
|
204
|
+
hash.fetch('another_undefined_key')
|
|
241
205
|
end
|
|
242
206
|
|
|
207
|
+
assert_equal '123', hash.fetch('another_undefined_key', '123')
|
|
208
|
+
assert_equal ["a", "b"], hash.keys
|
|
243
209
|
end
|
|
210
|
+
|
|
244
211
|
end
|
metadata
CHANGED
|
@@ -1,97 +1,69 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: casted_hash
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.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:
|
|
11
|
+
date: 2014-01-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: equalizer
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - '>='
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.0.7
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - '>='
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.0.7
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: activesupport
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - '>='
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :runtime
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - '>='
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
13
|
- !ruby/object:Gem::Dependency
|
|
42
14
|
name: bundler
|
|
43
15
|
requirement: !ruby/object:Gem::Requirement
|
|
44
16
|
requirements:
|
|
45
|
-
- -
|
|
17
|
+
- - ">="
|
|
46
18
|
- !ruby/object:Gem::Version
|
|
47
19
|
version: '1.3'
|
|
48
20
|
type: :development
|
|
49
21
|
prerelease: false
|
|
50
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
23
|
requirements:
|
|
52
|
-
- -
|
|
24
|
+
- - ">="
|
|
53
25
|
- !ruby/object:Gem::Version
|
|
54
26
|
version: '1.3'
|
|
55
27
|
- !ruby/object:Gem::Dependency
|
|
56
28
|
name: rake
|
|
57
29
|
requirement: !ruby/object:Gem::Requirement
|
|
58
30
|
requirements:
|
|
59
|
-
- -
|
|
31
|
+
- - ">="
|
|
60
32
|
- !ruby/object:Gem::Version
|
|
61
33
|
version: '0'
|
|
62
34
|
type: :development
|
|
63
35
|
prerelease: false
|
|
64
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
37
|
requirements:
|
|
66
|
-
- -
|
|
38
|
+
- - ">="
|
|
67
39
|
- !ruby/object:Gem::Version
|
|
68
40
|
version: '0'
|
|
69
41
|
- !ruby/object:Gem::Dependency
|
|
70
42
|
name: minitest
|
|
71
43
|
requirement: !ruby/object:Gem::Requirement
|
|
72
44
|
requirements:
|
|
73
|
-
- - ~>
|
|
45
|
+
- - "~>"
|
|
74
46
|
- !ruby/object:Gem::Version
|
|
75
47
|
version: '5'
|
|
76
48
|
type: :development
|
|
77
49
|
prerelease: false
|
|
78
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
51
|
requirements:
|
|
80
|
-
- - ~>
|
|
52
|
+
- - "~>"
|
|
81
53
|
- !ruby/object:Gem::Version
|
|
82
54
|
version: '5'
|
|
83
55
|
- !ruby/object:Gem::Dependency
|
|
84
56
|
name: coveralls
|
|
85
57
|
requirement: !ruby/object:Gem::Requirement
|
|
86
58
|
requirements:
|
|
87
|
-
- -
|
|
59
|
+
- - ">="
|
|
88
60
|
- !ruby/object:Gem::Version
|
|
89
61
|
version: '0'
|
|
90
62
|
type: :development
|
|
91
63
|
prerelease: false
|
|
92
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
65
|
requirements:
|
|
94
|
-
- -
|
|
66
|
+
- - ">="
|
|
95
67
|
- !ruby/object:Gem::Version
|
|
96
68
|
version: '0'
|
|
97
69
|
description: A casted hash
|
|
@@ -101,15 +73,13 @@ executables: []
|
|
|
101
73
|
extensions: []
|
|
102
74
|
extra_rdoc_files: []
|
|
103
75
|
files:
|
|
104
|
-
- .gitignore
|
|
76
|
+
- ".gitignore"
|
|
105
77
|
- Gemfile
|
|
106
78
|
- LICENSE.txt
|
|
107
79
|
- README.md
|
|
108
80
|
- Rakefile
|
|
109
81
|
- casted_hash.gemspec
|
|
110
82
|
- lib/casted_hash.rb
|
|
111
|
-
- lib/casted_hash/value.rb
|
|
112
|
-
- lib/casted_hash/version.rb
|
|
113
83
|
- test/helper.rb
|
|
114
84
|
- test/test_casted_hash.rb
|
|
115
85
|
homepage:
|
|
@@ -121,17 +91,17 @@ require_paths:
|
|
|
121
91
|
- lib
|
|
122
92
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
93
|
requirements:
|
|
124
|
-
- -
|
|
94
|
+
- - ">="
|
|
125
95
|
- !ruby/object:Gem::Version
|
|
126
96
|
version: '0'
|
|
127
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
98
|
requirements:
|
|
129
|
-
- -
|
|
99
|
+
- - ">="
|
|
130
100
|
- !ruby/object:Gem::Version
|
|
131
101
|
version: '0'
|
|
132
102
|
requirements: []
|
|
133
103
|
rubyforge_project:
|
|
134
|
-
rubygems_version: 2.0
|
|
104
|
+
rubygems_version: 2.2.0
|
|
135
105
|
signing_key:
|
|
136
106
|
specification_version: 4
|
|
137
107
|
summary: A casted hash
|
data/lib/casted_hash/value.rb
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
class CastedHash
|
|
2
|
-
class Value
|
|
3
|
-
include Equalizer.new(:value)
|
|
4
|
-
attr_reader :value
|
|
5
|
-
attr_accessor :casted_hash
|
|
6
|
-
|
|
7
|
-
def initialize(value, casted_hash)
|
|
8
|
-
@value = value
|
|
9
|
-
@casted_hash = casted_hash
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def casted_value
|
|
13
|
-
cast!
|
|
14
|
-
@value
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def casted?
|
|
18
|
-
!!@casted
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def cast!
|
|
22
|
-
return if casted?
|
|
23
|
-
raise SystemStackError, "Cannot cast value that is currently being cast" if @casting
|
|
24
|
-
|
|
25
|
-
@casting = true
|
|
26
|
-
|
|
27
|
-
@value = casted_hash.cast_proc.call(value)
|
|
28
|
-
ensure
|
|
29
|
-
@casted = true
|
|
30
|
-
@casting = false
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
data/lib/casted_hash/version.rb
DELETED