composite_type 0.1.1 → 0.2.2

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: 79b73ddf6ca69a94ade50421d460271d88bfa71c
4
- data.tar.gz: eff100ef24de4b9136566c47bd123eafe63491d0
3
+ metadata.gz: ae4bbf53d86ecc2c5e9ff994ccb7d5314fa163bd
4
+ data.tar.gz: 8866e977bf37b1bb094b30bc9dfb101d7dd126f0
5
5
  SHA512:
6
- metadata.gz: 0be9100aa76f309188b51710feb30837f760c03556fa7a76f92541227811bb3499e62cbc8de7b395a045b47f17c98349968758c6800813773d4527263f805fe3
7
- data.tar.gz: d05c6b593fee921e608bcb581c3478fb1b2b1d85ba3f2dd5c7582dac0ff3d12d5ad976be1afd3f27657aee22e3054590725b73f6de2422a7bfc5da570fbb7d8e
6
+ metadata.gz: '06584bde3409c9835559d40125b4c3d63ebc53e40adcddf0aacf2db473ae524d87fc04e2617054991a06863cdaab5ffc86e86c6933b9eca6f049984fe5b6af73'
7
+ data.tar.gz: 92314b05a2ee942bd02781f30524f4d57bc5eed7d10b8f4d1cfec45dd6b7bce9a7b740ce01871b5ae1874b5a800a86561e34ad339768f2be20215e1cab34955d
data/README.md CHANGED
@@ -13,7 +13,7 @@ Defining types through Modules:
13
13
 
14
14
  module Even
15
15
  def self.=== x
16
- Integer === x and x.even?
16
+ Integer === x and x.even?
17
17
  end
18
18
  end
19
19
  Array.of(Even) === [ 2, 4, 10 ]
@@ -29,14 +29,17 @@ Thus composite types can be used in "case when" clauses:
29
29
  Logical operators: #|, #&, #~ are supported:
30
30
 
31
31
  a = [ 1, 2, 3 ]
32
- Array.of(Positive & Numeric) === a # => true
33
- Array.of(~ NilClass) === a # => false
32
+ Array.of(Positive & Integer) === a # => true
33
+ Array.of(~ NilClass) === a # => true
34
34
 
35
35
  b = [ 1, -2, 3 ]
36
- Array.of(Positive & Numeric) === b # => false
37
-
38
- c = [ 1, nil, 3 ]
39
- Array.of(~ NilClass) === c # => false
36
+ Array.of(Positive & Integer) === b # => false
37
+
38
+ c = [ 1, 1.5, 3 ]
39
+ Array.of(Positive & Integer) === c # => false
40
+
41
+ d = [ 1, nil, 3 ]
42
+ Array.of(~ NilClass) === d # => false
40
43
 
41
44
  Composite types are cached indefinitely, therefore anonymous Modules cannot be composed.
42
45
 
@@ -19,10 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
23
- spec.add_development_dependency "rspec", "~> 3.0"
24
22
  spec.add_development_dependency "simplecov", "~> 0.8"
25
- spec.add_development_dependency "pry", "~> 0.9"
26
- spec.add_development_dependency "guard", "~> 2.6"
27
- spec.add_development_dependency "guard-rspec", "~> 4.3"
23
+ spec.add_development_dependency "pry", "~> 0.10"
24
+ spec.add_development_dependency "guard", "~> 2.14"
25
+ spec.add_development_dependency "guard-rspec", "~> 4.7"
28
26
  end
@@ -23,16 +23,27 @@ class Module
23
23
  end
24
24
 
25
25
  # Matches nothing.
26
- module Void
26
+ module VoidType
27
27
  def === x
28
28
  false
29
29
  end
30
+
31
+ def >= t
32
+ self == t
33
+ end
30
34
  end
35
+ Void = Class.new.extend(VoidType)
31
36
 
32
37
  class ContainerType < CompositeType
33
38
  def === x
34
39
  @_t[0] === x and x.all?{|e| @_t[1] === e }
35
40
  end
41
+
42
+ def >= t
43
+ super or
44
+ t.is_a?(self.class) and @_t.zip(t._t).all?{|e1, e2| e1 >= e2 }
45
+ end
46
+
36
47
  def to_s
37
48
  @to_s ||= "#{@_t[0]}.of(#{@_t[1]})".freeze
38
49
  end
@@ -54,6 +65,12 @@ class Module
54
65
  @_t.all?{|t| t === x[i += 1]}
55
66
  end
56
67
  end
68
+
69
+ def >= t
70
+ super or
71
+ t.is_a?(self.class) and @_t.zip(t._t).all?{|e1, e2| e1 >= e2 }
72
+ end
73
+
57
74
  def to_s
58
75
  @to_s ||= "#{@_t[0]}.with(#{@_t[1..-1] * ','})".freeze
59
76
  end
@@ -61,8 +78,8 @@ class Module
61
78
 
62
79
  # Constructs a type of Enumerable elements.
63
80
  #
64
- # String.with(Integer, Float) === [ "foo", 1, 1.2 ]
65
- # Hash.of(String.with(Integer))
81
+ # String.with(Integer, Float) === [ "foo", 1, 1.2 ]
82
+ # Hash.of(String.with(Integer))
66
83
  def with *types
67
84
  EnumeratedType.new_cached(self, *types)
68
85
  end
@@ -71,6 +88,18 @@ class Module
71
88
  def === x
72
89
  @_t[0] === x or @_t[1] === x
73
90
  end
91
+
92
+ def >= t
93
+ case
94
+ when super
95
+ true
96
+ when t.is_a?(self.class)
97
+ t._t.all?{|e2| @_t.any?{|e1| e1 >= e2}}
98
+ else
99
+ @_t.any?{|e1| e1 >= t}
100
+ end
101
+ end
102
+
74
103
  def to_s
75
104
  @to_s ||= "(#{@_t[0]}|#{@_t[1]})".freeze
76
105
  end
@@ -78,7 +107,7 @@ class Module
78
107
 
79
108
  # Constructs a type which can be A OR B.
80
109
  #
81
- # Array.of(String|Integer)
110
+ # Array.of(String|Integer)
82
111
  def | t
83
112
  case
84
113
  when t <= self
@@ -86,7 +115,9 @@ class Module
86
115
  when self <= t
87
116
  t
88
117
  else
89
- DisjunctiveType.new_cached(self, t)
118
+ a, b = self, t
119
+ a, b = b, a if a.to_s > b.to_s
120
+ DisjunctiveType.new_cached(a, b)
90
121
  end
91
122
  end
92
123
 
@@ -94,6 +125,18 @@ class Module
94
125
  def === x
95
126
  @_t[0] === x and @_t[1] === x
96
127
  end
128
+
129
+ def >= t
130
+ case
131
+ when super
132
+ true
133
+ when t.is_a?(self.class)
134
+ t._t.all?{|e2| @_t.all?{|e1| e1 >= e2}}
135
+ else
136
+ @_t.all?{|e1| e1 >= t}
137
+ end
138
+ end
139
+
97
140
  def to_s
98
141
  @to_s ||= "(#{@_t[0]}&#{@_t[1]})".freeze
99
142
  end
@@ -103,24 +146,47 @@ class Module
103
146
  #
104
147
  # Array.of(Positive & Integer)
105
148
  def & t
106
- ConjunctiveType.new_cached(self, t)
149
+ case
150
+ when equal?(t)
151
+ self
152
+ else
153
+ a, b = self, t
154
+ a, b = b, a if a.to_s > b.to_s
155
+ ConjunctiveType.new_cached(a, b)
156
+ end
107
157
  end
108
158
 
109
159
  class NegativeType < CompositeType
110
160
  def === x
111
161
  ! (@_t[0] === x)
112
162
  end
163
+
164
+ def >= t
165
+ t.is_a?(self.class) and
166
+ t._t[0] >= @_t[0]
167
+ end
168
+
113
169
  def to_s
114
170
  @to_s ||= "(~#{@_t[0]})".freeze
115
171
  end
172
+
173
+ INVERSE_MAP = {
174
+ }
175
+ def self.inverse(a, b)
176
+ INVERSE_MAP[a] = b
177
+ INVERSE_MAP[b] = a
178
+ end
179
+ inverse(Object, Void)
116
180
  end
117
181
 
118
182
  # Constructs a type which must not be A.
119
183
  #
120
184
  # Array.of(~ NilClass)
121
185
  def ~@
122
- case self
123
- when NegativeType
186
+ case
187
+ when x = NegativeType::INVERSE_MAP[self]
188
+ x
189
+ when self.is_a?(NegativeType)
124
190
  self._t.first
125
191
  else
126
192
  NegativeType.new_cached(self)
@@ -161,6 +227,7 @@ module NonPositive
161
227
  def self.=== x
162
228
  x <= 0 rescue nil
163
229
  end
230
+ Module::NegativeType.inverse(self, Positive)
164
231
  end
165
232
 
166
233
  # Objects that are Numericlike and >= 0.
@@ -168,6 +235,7 @@ module NonNegative
168
235
  def self.=== x
169
236
  x >= 0 rescue nil
170
237
  end
238
+ Module::NegativeType.inverse(self, Negative)
171
239
  end
172
240
 
173
241
  # Objects that can do IO.
@@ -1,3 +1,3 @@
1
1
  module CompositeType
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -1,7 +1,14 @@
1
1
  require 'spec_helper'
2
2
  require 'composite_type'
3
3
 
4
- describe Class::CompositeType do
4
+ describe Module::CompositeType do
5
+ module A; end
6
+ module B; end
7
+ module C; include A; end
8
+ module D; include B; end
9
+ module E; include A, B; end
10
+ module F; include A, B; end
11
+
5
12
  it "should cache instances" do
6
13
  t1 = Array.of(String.with(~ Float | Symbol & Hash))
7
14
  t2 = Array.of(String.with(~ Float | Symbol & Hash))
@@ -14,6 +21,20 @@ describe Class::CompositeType do
14
21
  }.to raise_error(Module::CompositeType::Error, "cannot create CompositeType from unamed object")
15
22
  end
16
23
 
24
+ context Module::Void do
25
+ subject { Module::Void }
26
+ it "does not match anything" do
27
+ expect(subject === Object.new) .to be_falsey
28
+ end
29
+ context "#>=" do
30
+ it "is disjoint from everything" do
31
+ expect( subject >= subject ) .to be_truthy
32
+ expect( Object >= subject ) .to be_truthy
33
+ expect( subject >= Object ) .to be_falsey
34
+ end
35
+ end
36
+ end
37
+
17
38
  context Numericlike do
18
39
  subject { Numericlike }
19
40
  let(:numeric_like) do
@@ -43,125 +64,102 @@ describe Class::CompositeType do
43
64
 
44
65
  context "EnumeratedType" do
45
66
  subject { Integer.with(Symbol, String) }
46
- it "should not fail" do
67
+ it "is true for respective unmatches" do
47
68
  expect(subject === [ 1, :symbol, "string" ]) .to be_truthy
48
69
  end
49
- it "should fail" do
70
+ it "is false for respective unmatches" do
50
71
  expect(subject === [ ]) .to be_falsey
51
- end
52
- it "should fail" do
53
72
  expect(subject === [ 1, :symbol, :wrong ]) .to be_falsey
54
73
  end
55
- it "should fail" do
74
+ it "is false for too many elements" do
56
75
  expect(subject === [ 1, :symbol, "string", :too_many]) .to be_falsey
57
76
  end
58
77
  end
59
78
 
60
79
  context "ContainerType" do
61
80
  subject { Array.of(String) }
62
- it "should not fail when empty" do
81
+ it "is true when empty" do
63
82
  expect(subject === [ ]) .to be_truthy
64
83
  end
65
- it "should not fail with a matching element" do
84
+ it "is true with a matching element" do
66
85
  expect(subject === [ "String" ]) .to be_truthy
67
86
  end
68
- it "should fail when contains unmatching element" do
87
+ it "is false with an unmatching element" do
69
88
  expect(subject === [ "String", 1234 ]) .to be_falsey
70
89
  end
71
- it "should fail when is not an Enumerable" do
90
+ it "is false without an Enumerable" do
72
91
  expect(subject === 1234) .to be_falsey
73
92
  end
74
- it "should fail when is not equvalent" do
93
+ it "is false when not equvalent" do
75
94
  expect(subject === { }) .to be_falsey
76
95
  end
77
96
  end
78
97
 
79
98
  context "EnumeratedType" do
80
99
  subject { Hash.of(String.with(Integer)) }
81
- it "should not fail when empty" do
100
+ it "matches" do
82
101
  expect(subject === { }) .to be_truthy
83
- end
84
-
85
- it "should not fail" do
86
102
  expect(subject === { "foo" => 1 }) .to be_truthy
87
- end
88
-
89
- it "should fail" do
90
103
  expect(subject === { "foo" => :symbol }) .to be_falsey
91
- end
92
-
93
- it "should fail" do
94
104
  expect(subject === { :symbol => 2 }) .to be_falsey
95
105
  end
96
106
  end
97
107
 
98
108
  context "DisjunctiveType" do
99
- it "should reduce to the greater type if A or B are subclasses of each other" do
100
- expect(Float | Numeric) .to equal(Numeric)
101
- expect(Numeric | Float ) .to equal(Numeric)
102
- expect(Numeric | Numeric) .to equal(Numeric)
103
- end
104
-
105
- it "should not reduce if A and B are disjunctive" do
106
- expect((Numericlike | Numeric).to_s) .to eq("(Numericlike|Numeric)")
107
- expect((String | Array).to_s) .to eq("(String|Array)")
109
+ it "matches" do
110
+ expect((String | Integer) === "String") .to be_truthy
111
+ expect((String | Integer) === 1234) .to be_truthy
112
+ expect((String | Integer) === :symbol) .to be_falsey
108
113
  end
109
114
 
110
- it "should not fail when empty" do
111
- v = [ ]
112
- expect(Array.of(String | Integer) === v) .to be_truthy
115
+ it "rewrites B | A => A | B" do
116
+ expect((B | A)) .to equal((A | B))
113
117
  end
114
118
 
115
- it "should not fail" do
116
- v = [ "String", 1234 ]
117
- expect(Array.of(String | Integer) === v) .to be_truthy
119
+ it "reduces to the greater type if A or B are subclasses of each other" do
120
+ expect(Float | Numeric) .to equal(Numeric)
121
+ expect(Numeric | Float ) .to equal(Numeric)
122
+ expect(Numeric | Numeric) .to equal(Numeric)
118
123
  end
119
124
 
120
- it "should fail" do
121
- v = [ "String", 1234, :symbol ]
122
- expect(Array.of(String | Integer) === v) .to be_falsey
125
+ it "does not reduce if A and B are disjunctive" do
126
+ expect((Numericlike | Numeric).to_s) .to eq("(Numeric|Numericlike)")
127
+ expect((String | Array).to_s) .to eq("(Array|String)")
123
128
  end
124
129
  end
125
130
 
126
131
  context "ConjunctiveType" do
127
- subject { Array.of(Positive & Integer) }
128
- it "should not fail when empty" do
129
- v = [ ]
130
- expect(subject === v) .to be_truthy
131
- end
132
-
133
- it "should not fail" do
134
- v = [ 1, 2 ]
135
- expect(subject === v) .to be_truthy
132
+ subject { Positive & Integer }
133
+ it "matches" do
134
+ expect(subject === 1) .to be_truthy
135
+ expect(subject === 0) .to be_falsey
136
+ expect(subject === 0.0) .to be_falsey
137
+ expect(subject === :symbol) .to be_falsey
136
138
  end
137
-
138
- it "should fail" do
139
- v = [ 0, 1 ]
140
- expect(subject === v) .to be_falsey
139
+ it "folds A & A => A" do
140
+ expect((A & A)) .to equal(A)
141
141
  end
142
-
143
- it "should fail" do
144
- v = [ 1, :symbol ]
145
- expect(subject === v) .to be_falsey
142
+ it "rewrites B & A => A & B" do
143
+ expect((B & A)) .to equal((A & B))
146
144
  end
147
145
  end
148
146
 
149
147
  context "NegativeType" do
150
- it "~~A == A" do
151
- t = String
152
- expect(~ ~ t) .to equal(t)
148
+ it "matches" do
149
+ expect((~ NilClass) === 1) .to be_truthy
150
+ expect((~ NilClass) === :symbol) .to be_truthy
151
+ expect((~ NilClass) === nil) .to be_falsey
153
152
  end
154
153
 
155
- it "should be true for match" do
156
- v = [ 1, :symbol ]
157
- expect(Array.of(~ NilClass) === v) .to be_truthy
154
+ it "rewrites (~ (~ A)) => A" do
155
+ expect(~ ~ A) .to equal(A)
158
156
  end
159
157
 
160
- it "should be false for match" do
161
- v = [ 1, nil, :symbol ]
162
- expect((~ NilClass) === 1) .to be_truthy
163
- expect((~ NilClass) === nil) .to be_falsey
164
- expect(Array.of(~ NilClass) === v) .to be_falsey
158
+ it "rewrites inverse types" do
159
+ expect(~ Object) .to equal(Module::Void)
160
+ expect(~ Module::Void) .to equal(Object)
161
+ expect(~ Negative) .to equal(NonNegative)
162
+ expect(~ NonNegative) .to equal(Negative)
165
163
  end
166
164
  end
167
165
 
@@ -209,6 +207,44 @@ describe Class::CompositeType do
209
207
  end
210
208
  end
211
209
 
210
+ context "#>=" do
211
+ it "returns true where left side is a supertype of right side" do
212
+ expect( Array.of(Object) >= Array.of(String) ) .to be_truthy
213
+ expect( Array.of(String) >= Array.of(Object) ) .to be_falsey
214
+ expect( Array.of(String) >= Object ) .to be_falsey
215
+
216
+ expect( Numeric.with(Integer) >= Numeric.with(Bignum) ) .to be_truthy
217
+ expect( Numeric.with(Integer) >= Float.with(Bignum) ) .to be_truthy
218
+ expect( Numeric.with(Integer) >= Object.with(Bignum) ) .to be_falsey
219
+ expect( Numeric.with(Integer) >= Float.with(Object) ) .to be_falsey
220
+ expect( Numeric.with(Integer) >= Integer.with(Object) ) .to be_falsey
221
+
222
+ expect( Hash.of(Symbol.with(Object)) >= Hash.of(Symbol.with(String)) ) .to be_truthy
223
+ expect( Hash.of(Symbol.with(Object)) >= Hash.of(Symbol.with(Fixnum)) ) .to be_truthy
224
+ expect( Hash.of(Symbol.with(String)) >= Hash.of(Symbol.with(Fixnum)) ) .to be_falsey
225
+ expect( Hash.of(Symbol.with(Object)) >= Array.of(String) ) .to be_falsey
226
+
227
+ expect( (Integer | Float) >= (Integer | Float) ) .to be_truthy
228
+ expect( (Integer | Float) >= Integer ) .to be_truthy
229
+ expect( (Integer | Float) >= Fixnum ) .to be_truthy
230
+ expect( (Integer | Float) >= Bignum ) .to be_truthy
231
+ expect( (Fixnum | Float) >= Bignum ) .to be_falsey
232
+ expect( (Fixnum | Float) >= (Float | Bignum) ) .to be_falsey
233
+ expect( (Integer | Float) >= (Float | Fixnum) ) .to be_truthy
234
+
235
+ expect( (Positive & Integer) >= (Integer & Positive) ) .to be_truthy
236
+ expect( (A & B) >= E ) .to be_truthy
237
+ expect( (A & B) >= C ) .to be_falsey
238
+ expect( (A & B) >= (E & F) ) .to be_truthy
239
+ expect( (Positive & Integer) >= Integer ) .to be_falsey
240
+
241
+ expect( (~ A) >= B ) .to be_falsey
242
+ expect( (~ Numeric) >= (~ Fixnum) ) .to be_falsey
243
+ expect( (~ Fixnum) >= (~ Numeric) ) .to be_truthy
244
+ expect( (~ Object) >= (~ Fixnum) ) .to be_falsey
245
+ end
246
+ end
247
+
212
248
  context "misc" do
213
249
  it "example 1" do
214
250
  h = { "a" => 1, "b" => :symbol }
@@ -223,6 +259,5 @@ describe Class::CompositeType do
223
259
  it "should handle to_s" do
224
260
  expect(Hash.of(String.with(Integer | Symbol)).to_s) .to eq("Hash.of(String.with((Integer|Symbol)))")
225
261
  end
226
-
227
262
  end
228
263
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: composite_type
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kurt Stephens
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-27 00:00:00.000000000 Z
11
+ date: 2016-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,34 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.0'
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: simplecov
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -72,42 +44,42 @@ dependencies:
72
44
  requirements:
73
45
  - - "~>"
74
46
  - !ruby/object:Gem::Version
75
- version: '0.9'
47
+ version: '0.10'
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
- version: '0.9'
54
+ version: '0.10'
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: guard
85
57
  requirement: !ruby/object:Gem::Requirement
86
58
  requirements:
87
59
  - - "~>"
88
60
  - !ruby/object:Gem::Version
89
- version: '2.6'
61
+ version: '2.14'
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
- version: '2.6'
68
+ version: '2.14'
97
69
  - !ruby/object:Gem::Dependency
98
70
  name: guard-rspec
99
71
  requirement: !ruby/object:Gem::Requirement
100
72
  requirements:
101
73
  - - "~>"
102
74
  - !ruby/object:Gem::Version
103
- version: '4.3'
75
+ version: '4.7'
104
76
  type: :development
105
77
  prerelease: false
106
78
  version_requirements: !ruby/object:Gem::Requirement
107
79
  requirements:
108
80
  - - "~>"
109
81
  - !ruby/object:Gem::Version
110
- version: '4.3'
82
+ version: '4.7'
111
83
  description: Composite Types for Ruby
112
84
  email:
113
85
  - ks.github@kurtstephens.com
@@ -147,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
119
  version: '0'
148
120
  requirements: []
149
121
  rubyforge_project:
150
- rubygems_version: 2.2.2
122
+ rubygems_version: 2.6.8
151
123
  signing_key:
152
124
  specification_version: 4
153
125
  summary: Array.of(String)