hash_initialized_struct 1.1.0 → 1.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/lib/hash_initialized_struct/version.rb +1 -1
- data/lib/hash_initialized_struct.rb +28 -10
- data/spec/hash_initialized_struct_spec.rb +28 -13
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a019905cb0578ccd137f19e03bc4506c4394d70
|
4
|
+
data.tar.gz: d995895f24be535e41f72b7c55d8f074b05dbf66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eaa60f77a463b145fe836d23b06b1953ef64959a99b78e14c603280de7e655b482c5abcca48e2ceb921cd2ed8cae716fbadcc3417c4744426e80fd3b86d1bea8
|
7
|
+
data.tar.gz: 9c3990737ae43394e9ea0f2d3ea8c7fe186b3165c3718edc3568f894d3cae8a5517cdc000cf4a230610b34c97cf5bfeadf308d11232ed5c274cd4ba271271a4b
|
@@ -35,16 +35,10 @@ class HashInitializedStruct
|
|
35
35
|
|
36
36
|
def initialize(attrs)
|
37
37
|
provided = attrs.keys
|
38
|
-
needed =
|
39
|
-
(provided
|
40
|
-
|
41
|
-
|
42
|
-
(needed - provided).tap do |missing|
|
43
|
-
raise ArgumentError, "Missing keys: #{missing.map(&:inspect).join(', ')}" unless missing.empty?
|
44
|
-
end
|
45
|
-
attrs.each do |attr,value|
|
46
|
-
instance_variable_set("@#{attr}", value)
|
47
|
-
end
|
38
|
+
needed = needed_keys
|
39
|
+
self.raise_on_unrecognised_keys(provided, needed)
|
40
|
+
self.raise_on_missing_keys(provided, needed)
|
41
|
+
set_attributes(attrs)
|
48
42
|
end
|
49
43
|
|
50
44
|
def to_h
|
@@ -52,6 +46,30 @@ class HashInitializedStruct
|
|
52
46
|
Hash[ self.class::STRUCT_ATTRS.map {|key| [key, self.public_send(key)]} ]
|
53
47
|
end
|
54
48
|
alias :to_hash :to_h
|
49
|
+
|
50
|
+
protected
|
51
|
+
|
52
|
+
def needed_keys
|
53
|
+
self.class::STRUCT_ATTRS
|
54
|
+
end
|
55
|
+
|
56
|
+
def raise_on_unrecognised_keys(provided, needed)
|
57
|
+
(provided - needed).tap do |unknown|
|
58
|
+
raise ArgumentError, "Unrecognised keys: #{unknown.map(&:inspect).join(', ')}" unless unknown.empty?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def raise_on_missing_keys(provided, needed)
|
63
|
+
(needed - provided).tap do |missing|
|
64
|
+
raise ArgumentError, "Missing keys: #{missing.map(&:inspect).join(', ')}" unless missing.empty?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def set_attributes(attrs)
|
69
|
+
attrs.each do |attr,value|
|
70
|
+
instance_variable_set("@#{attr}", value)
|
71
|
+
end
|
72
|
+
end
|
55
73
|
end
|
56
74
|
end
|
57
75
|
end
|
@@ -46,23 +46,38 @@ describe "HashInitializedStruct" do
|
|
46
46
|
expect(point.to_h).to eq Hash(point) # to_h == to_hash
|
47
47
|
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
49
|
+
describe "overriding the constructor" do
|
50
|
+
it "allows additional checks" do
|
51
|
+
# Could do this with an anonymous class and define_method, but we're trying to emulate
|
52
|
+
# how it might actually be used.
|
53
|
+
class My3DPoint < HashInitializedStruct.new(:x, :y, :z)
|
54
|
+
def initialize(attrs)
|
55
|
+
super
|
56
|
+
[x, y, z].each do |attr|
|
57
|
+
raise ArgumentError, "#{attr} must be a number" unless attr.kind_of?(Numeric)
|
58
|
+
end
|
57
59
|
end
|
58
60
|
end
|
61
|
+
|
62
|
+
good = My3DPoint.new(x: 1, y: 2, z: 9)
|
63
|
+
expect(good.x).to eq 1
|
64
|
+
|
65
|
+
expect {
|
66
|
+
My3DPoint.new(x: "1", y: nil, z: 9)
|
67
|
+
}.to raise_error(ArgumentError)
|
59
68
|
end
|
60
69
|
|
61
|
-
|
62
|
-
|
70
|
+
it "allows partial checks" do
|
71
|
+
class MyOptionally4DPoint < HashInitializedStruct.new(:x, :y, :z, :t)
|
72
|
+
def initialize(attrs)
|
73
|
+
provided = attrs.keys
|
74
|
+
raise_on_unrecognised_keys(provided, needed_keys)
|
75
|
+
set_attributes
|
76
|
+
end
|
77
|
+
end
|
63
78
|
|
64
|
-
|
65
|
-
|
66
|
-
|
79
|
+
good = My3DPoint.new(x: 1, y: 2, z: 9) # Missing :t
|
80
|
+
expect(good.x).to eq 1
|
81
|
+
end
|
67
82
|
end
|
68
83
|
end
|