named-parameters 0.0.7 → 0.0.8
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.
- data/README.md +89 -24
- data/RELEASENOTES +8 -0
- data/VERSION +1 -1
- data/lib/named-parameters/module.rb +16 -26
- data/named-parameters.gemspec +17 -19
- data/spec/named-parameters_spec.rb +21 -16
- metadata +6 -7
- data/.gitignore +0 -21
data/README.md
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
This gem simulates named-parameters in Ruby. It's a complement to the common
|
2
2
|
Ruby idiom of using `Hash` args to emulate the use of named parameters.
|
3
3
|
|
4
|
-
|
5
|
-
that allows a class to declare the parameters that are acceptable to a method.
|
6
|
-
|
7
|
-
The `has_named_parameters` dictates how the presence of these parameters are
|
8
|
-
enforced and raises an `ArgumentError` when a method invocation is made that
|
9
|
-
violates the rules for those parameters.
|
10
|
-
|
11
|
-
See: the [Named Parameter](http://en.wikipedia.org/wiki/named_parameter)
|
12
|
-
article from Wikipedia for more information.
|
4
|
+
Related: [Named Parameters in Ruby](http://www.jurisgalang.com/2010/11/09/named-parameters-in-ruby/)
|
13
5
|
|
14
6
|
Get It
|
15
7
|
------
|
@@ -95,7 +87,7 @@ And is applicable to both class and instance methods:
|
|
95
87
|
# ... do send mail stuff here ...
|
96
88
|
end
|
97
89
|
|
98
|
-
has_named_parameters :archive, :optional => [ :method => 'zip' ]
|
90
|
+
has_named_parameters :'self.archive', :optional => [ :method => 'zip' ]
|
99
91
|
def self.archive options = { }
|
100
92
|
# ... do mail archiving stuff here ...
|
101
93
|
end
|
@@ -104,23 +96,25 @@ And is applicable to both class and instance methods:
|
|
104
96
|
Shortcuts
|
105
97
|
---------
|
106
98
|
In addition to the `has_named_parameters` method, `NamedParameters` also comes
|
107
|
-
with two convenience methods for applying
|
99
|
+
with two convenience methods for implicitly applying parameter specs for
|
100
|
+
constructors.
|
108
101
|
|
109
|
-
Use the
|
102
|
+
Use the `requires` clause to declare what parameters a class expects when it
|
110
103
|
is instantiated:
|
111
104
|
|
112
105
|
class GoogleStorage
|
113
|
-
requires
|
106
|
+
requires :'access-key', :'secret-key'
|
114
107
|
|
115
108
|
def initialize options
|
116
109
|
# ... do googly stuff here ...
|
117
110
|
end
|
118
111
|
end
|
119
112
|
|
120
|
-
Use the
|
113
|
+
Use the `recognizes` clause to specify the optional parameters for a class
|
114
|
+
when it is instantiated:
|
121
115
|
|
122
116
|
class GoogleStorage
|
123
|
-
recognizes
|
117
|
+
recognizes :'group-email', :'apps-domain'
|
124
118
|
|
125
119
|
def initialize options
|
126
120
|
# ... do googly stuff here ...
|
@@ -130,14 +124,22 @@ Use the **`recognizes`** clause to specify optional parameters for constructors:
|
|
130
124
|
You may also specify default values for parameters when using these clauses:
|
131
125
|
|
132
126
|
class GoogleStorage
|
133
|
-
requires
|
134
|
-
recognizes [
|
127
|
+
requires :'access-key', :'secret-key'
|
128
|
+
recognizes [ :'group-email', 'group@example.org' ], [ :'apps-domain', 'example.org' ]
|
135
129
|
|
136
130
|
def initialize options
|
137
131
|
# ... do googly stuff here ...
|
138
132
|
end
|
139
133
|
end
|
140
134
|
|
135
|
+
The `requires` and `recognizes` clause is equivalent to declaring the lines
|
136
|
+
in a class definition:
|
137
|
+
|
138
|
+
has_named_parameters :'self.new', :required => params, :strict
|
139
|
+
has_named_parameters :initialize, :required => params, :strict
|
140
|
+
has_named_parameters :'self.new', :optional => params, :strict
|
141
|
+
has_named_parameters :initialize, :optional => params, :strict
|
142
|
+
|
141
143
|
Permissive Mode
|
142
144
|
---------------
|
143
145
|
When a method is declared with `has_named_parameters` that method will only
|
@@ -173,15 +175,15 @@ The `:required` and `:oneof` parameters will still be expected:
|
|
173
175
|
For clarity you should skip the `:optional` parameters list altogether when
|
174
176
|
using the `:permissive` mode.
|
175
177
|
|
176
|
-
|
177
|
-
|
178
|
+
However, the `requires` and `recognizes` clauses does not accept the `mode` argument.
|
179
|
+
If you need to make a constructor's optional parameter spec permissive, use
|
180
|
+
the `has_named_parameters` clause instead:
|
178
181
|
|
179
|
-
|
180
|
-
|
182
|
+
has_named_parameters :'self.new', :required => params, :permissive
|
183
|
+
has_named_parameters :initialize, :required => params, :permissive
|
181
184
|
|
182
|
-
|
183
|
-
|
184
|
-
clause altogether.
|
185
|
+
For brevity, since the mode is `:permissive`, the `:optional` parameters list
|
186
|
+
is skipped.
|
185
187
|
|
186
188
|
How It Works
|
187
189
|
------------
|
@@ -246,6 +248,69 @@ For the above case, it might be better to refactor:
|
|
246
248
|
|
247
249
|
# result:
|
248
250
|
# => path: /xxx, options: {}
|
251
|
+
|
252
|
+
Class vs Instance Methods
|
253
|
+
-------------------------
|
254
|
+
Parameter spec declarations are not shared between class and instance
|
255
|
+
methods even if they share the same name.
|
256
|
+
|
257
|
+
For example, the following `has_named_parameters` declaration below is only
|
258
|
+
applicable to the instance method `exec`:
|
259
|
+
|
260
|
+
class Command
|
261
|
+
has_named_parameters :exec, :required => :x
|
262
|
+
def self.exec opts
|
263
|
+
# ...
|
264
|
+
end
|
265
|
+
|
266
|
+
def exec opts
|
267
|
+
# ...
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
# the following will *not* raise an ArgumentError because
|
272
|
+
# the has_named_parameter declaration applies only to the
|
273
|
+
# instance method exec...
|
274
|
+
Command.exec
|
275
|
+
|
276
|
+
# the following will raise an ArgumentError (as expected)
|
277
|
+
command = Command.new
|
278
|
+
command.exec
|
279
|
+
|
280
|
+
Prefix the method name with `self.` to apply parameter spec for class methods:
|
281
|
+
|
282
|
+
class Command
|
283
|
+
has_named_parameters :'self.exec', :required => :x
|
284
|
+
def self.exec opts
|
285
|
+
# ...
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# the following will now raise an ArgumentError (as expected)
|
290
|
+
Command.exec
|
291
|
+
|
292
|
+
In general, however, when a class has an instance and a class method using
|
293
|
+
the same name, for most cases, one simply delegates to another and will share
|
294
|
+
the same requirements. So the examples cited above can be refactored:
|
295
|
+
|
296
|
+
class Command
|
297
|
+
has_named_parameters :'self.exec', :required => :x
|
298
|
+
def self.exec opts
|
299
|
+
# ...
|
300
|
+
end
|
301
|
+
|
302
|
+
def exec opts
|
303
|
+
Command.exec
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
# the following will raise an ArgumentError (as expected)
|
308
|
+
Command.exec
|
309
|
+
|
310
|
+
# the following will also raise an ArgumentError as it delegates to the
|
311
|
+
# class method and violates the parameter requirements
|
312
|
+
command = Command.new
|
313
|
+
command.exec
|
249
314
|
|
250
315
|
Dependencies
|
251
316
|
------------
|
data/RELEASENOTES
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
0.0.8 [Nov 22, 2010]
|
2
|
+
- [INTERNAL] Parameter spec will no longer be shared between singleton and
|
3
|
+
instance methods. Bonus performance improvement: it no longer needs to keep
|
4
|
+
track of the parameter specs after the class is declared.
|
5
|
+
- [INTERNAL] The mode argument is no longer entertained by the requires and
|
6
|
+
recognizes clause. Use the has_named_parameters clause on constructors if
|
7
|
+
permissive behavior is required on optional parameters.
|
8
|
+
|
1
9
|
0.0.7 [Nov 18, 2010]
|
2
10
|
- [FEATURE] Added support to distinguish named parameters declaration for
|
3
11
|
class and instance methods that uses the same names. So now you could do:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
@@ -122,45 +122,35 @@ module NamedParameters
|
|
122
122
|
|
123
123
|
# Convenience method, equivalent to declaring:
|
124
124
|
#
|
125
|
-
# has_named_parameters :'self.new', :required => params
|
126
|
-
# has_named_parameters :initialize, :required => params
|
125
|
+
# has_named_parameters :'self.new', :required => params, :strict
|
126
|
+
# has_named_parameters :initialize, :required => params, :strict
|
127
127
|
#
|
128
128
|
# @param [Array] params the lists of parameters. The list is expected
|
129
129
|
# to be an `Array` of symbols matching the names of the required
|
130
130
|
# parameters.
|
131
131
|
#
|
132
|
-
|
133
|
-
|
134
|
-
# Set it to `:permissive` to relax the requirement - `:required` and `:oneof`
|
135
|
-
# parameters will still be expected.
|
136
|
-
#
|
137
|
-
def requires params, mode = :strict
|
138
|
-
[ :new, :initialize ].each do |method|
|
132
|
+
def requires *params
|
133
|
+
[ :'self.new', :initialize ].each do |method|
|
139
134
|
spec = specs[key_for method] || { }
|
140
135
|
spec.merge!(:required => params)
|
141
|
-
has_named_parameters method, spec,
|
136
|
+
has_named_parameters method, spec, :strict
|
142
137
|
end
|
143
138
|
end
|
144
139
|
|
145
140
|
# Convenience method, equivalent to declaring:
|
146
141
|
#
|
147
|
-
# has_named_parameters :'self.new', :optional => params
|
148
|
-
# has_named_parameters :initialize, :optional => params
|
142
|
+
# has_named_parameters :'self.new', :optional => params, :strict
|
143
|
+
# has_named_parameters :initialize, :optional => params, :strict
|
149
144
|
#
|
150
145
|
# @param [Array] params the lists of parameters. The list is expected
|
151
146
|
# to be an `Array` of symbols matching the names of the optional
|
152
147
|
# parameters.
|
153
148
|
#
|
154
|
-
|
155
|
-
|
156
|
-
# Set it to `:permissive` to relax the requirement - `:required` and `:oneof`
|
157
|
-
# parameters will still be expected.
|
158
|
-
#
|
159
|
-
def recognizes params, mode = :strict
|
160
|
-
[ :new, :initialize ].each do |method|
|
149
|
+
def recognizes *params
|
150
|
+
[ :'self.new', :initialize ].each do |method|
|
161
151
|
spec = specs[key_for method] || { }
|
162
152
|
spec.merge!(:optional => params)
|
163
|
-
has_named_parameters method, spec,
|
153
|
+
has_named_parameters method, spec, :strict
|
164
154
|
end
|
165
155
|
end
|
166
156
|
|
@@ -193,15 +183,15 @@ module NamedParameters
|
|
193
183
|
# ...
|
194
184
|
# end
|
195
185
|
#
|
196
|
-
def validates_arguments method, param, &block
|
197
|
-
|
198
|
-
end
|
186
|
+
#def validates_arguments method, param, &block
|
187
|
+
# # TODO: IMPLEMENT
|
188
|
+
#end
|
199
189
|
|
200
190
|
# add instrumentation for class methods
|
201
191
|
def singleton_method_added name # :nodoc:
|
202
|
-
instrument name do
|
192
|
+
instrument :"self.#{name}" do
|
203
193
|
method = self.eigenclass.instance_method name
|
204
|
-
spec = specs
|
194
|
+
spec = specs.delete(key_for :"self.#{name}")
|
205
195
|
owner = "#{self.name}::"
|
206
196
|
eigenclass.instance_eval do
|
207
197
|
intercept method, owner, name, spec
|
@@ -214,7 +204,7 @@ module NamedParameters
|
|
214
204
|
def method_added name # :nodoc:
|
215
205
|
instrument name do
|
216
206
|
method = instance_method name
|
217
|
-
spec = specs
|
207
|
+
spec = specs.delete(key_for name)
|
218
208
|
owner = "#{self.name}#"
|
219
209
|
intercept method, owner, name, spec
|
220
210
|
end
|
data/named-parameters.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{named-parameters}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Juris Galang"]
|
12
|
-
s.date = %q{2010-11-
|
12
|
+
s.date = %q{2010-11-22}
|
13
13
|
s.description = %q{This gem simulates named-parameters in Ruby. It's a complement to the common
|
14
14
|
Ruby idiom of using `Hash` args to emulate the use of named parameters.
|
15
15
|
|
@@ -26,29 +26,27 @@ Gem::Specification.new do |s|
|
|
26
26
|
]
|
27
27
|
s.files = [
|
28
28
|
".document",
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
"spec/spec_helper.rb"
|
29
|
+
"GPL-LICENSE",
|
30
|
+
"MIT-LICENSE",
|
31
|
+
"README.md",
|
32
|
+
"RELEASENOTES",
|
33
|
+
"Rakefile",
|
34
|
+
"VERSION",
|
35
|
+
"lib/named-parameters.rb",
|
36
|
+
"lib/named-parameters/module.rb",
|
37
|
+
"lib/named-parameters/object.rb",
|
38
|
+
"named-parameters.gemspec",
|
39
|
+
"spec/named-parameters_spec.rb",
|
40
|
+
"spec/spec.opts",
|
41
|
+
"spec/spec_helper.rb"
|
43
42
|
]
|
44
43
|
s.homepage = %q{http://github.com/jurisgalang/named-parameters}
|
45
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
46
44
|
s.require_paths = ["lib"]
|
47
45
|
s.rubygems_version = %q{1.3.7}
|
48
46
|
s.summary = %q{Poor man's named-parameters in Ruby}
|
49
47
|
s.test_files = [
|
50
48
|
"spec/named-parameters_spec.rb",
|
51
|
-
|
49
|
+
"spec/spec_helper.rb"
|
52
50
|
]
|
53
51
|
|
54
52
|
if s.respond_to? :specification_version then
|
@@ -1,17 +1,20 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
+
# TODO: reorganize the tests for clarity
|
4
|
+
# TODO: need separate spec for the NamedParameters.validate_specs method
|
5
|
+
# TODO: factor out specs for required, recognizes, and has_named_parameters
|
3
6
|
describe "NamedParameters" do
|
4
7
|
before :all do
|
5
8
|
class Foo
|
6
9
|
has_named_parameters :initialize, :required => :x, :optional => [ :y, :z ]
|
7
10
|
def initialize opts = {}; end
|
8
|
-
|
11
|
+
|
9
12
|
has_named_parameters :method_one, :required => :x, :optional => [ :y, :z ]
|
10
13
|
def method_one x, y, opts = {}; end
|
11
|
-
|
14
|
+
|
12
15
|
def method_two x, y, opts = {}; end
|
13
16
|
|
14
|
-
has_named_parameters :method_three, :required => :x, :optional => [ :y, :z ]
|
17
|
+
has_named_parameters :'self.method_three', :required => :x, :optional => [ :y, :z ]
|
15
18
|
def self.method_three x, y, opts = {}; end
|
16
19
|
|
17
20
|
def self.method_four x, y, opts = {}; end
|
@@ -35,7 +38,7 @@ describe "NamedParameters" do
|
|
35
38
|
|
36
39
|
has_named_parameters :method_with_many_optional, :optional => [ :x, :y ]
|
37
40
|
def method_with_many_optional opts = {}; end
|
38
|
-
|
41
|
+
|
39
42
|
has_named_parameters :method_with_one_of_each_requirement, :required => :w, :oneof => [ :x, :y ], :optional => :z
|
40
43
|
def method_with_one_of_each_requirement opts = {}; end
|
41
44
|
end
|
@@ -52,7 +55,7 @@ describe "NamedParameters" do
|
|
52
55
|
lambda{ Foo.new :x => :x, :y => :y }.should_not raise_error
|
53
56
|
lambda{ Foo.new :x => :x, :y => :y, :z => :z }.should_not raise_error
|
54
57
|
end
|
55
|
-
|
58
|
+
|
56
59
|
it "should enforce named parameters for instrumented instance methods" do
|
57
60
|
lambda{ @foo = Foo.new :x => :x, :y => :y, :z => :z }.should_not raise_error
|
58
61
|
lambda{ @foo.method_one :x }.should raise_error ArgumentError
|
@@ -64,7 +67,7 @@ describe "NamedParameters" do
|
|
64
67
|
lambda{ @foo.method_one :x, :y, :x => :x, :y => :y }.should_not raise_error
|
65
68
|
lambda{ @foo.method_one :x, :y, :x => :x, :y => :y, :z => :z }.should_not raise_error
|
66
69
|
end
|
67
|
-
|
70
|
+
|
68
71
|
it "should not enforce named parameters for un-instrumented instance methods" do
|
69
72
|
lambda{ @foo = Foo.new :x => :x, :y => :y, :z => :z }.should_not raise_error
|
70
73
|
lambda{ @foo.method_two :x }.should raise_error ArgumentError
|
@@ -135,15 +138,15 @@ describe "NamedParameters" do
|
|
135
138
|
lambda{ bar.method_with_one_of_each_requirement :w => :w, :y => :y, :z => :z }.should_not raise_error
|
136
139
|
lambda{ bar.method_with_one_of_each_requirement :w => :w, :x => :x, :z => :z, :a => :a }.should raise_error ArgumentError
|
137
140
|
end
|
138
|
-
|
141
|
+
|
139
142
|
it "should be able to supply the default values for optional parameters" do
|
140
143
|
class Zoo
|
141
144
|
has_named_parameters :method_with_one_optional_parameter, :optional => { :x => 1 }
|
142
145
|
def method_with_one_optional_parameter opts = { }; opts[:x]; end
|
143
|
-
|
146
|
+
|
144
147
|
has_named_parameters :method_with_many_optional_parameters, :optional => [ [ :x, 1 ], [ :y, 2 ] ]
|
145
148
|
def method_with_many_optional_parameters opts = { }; opts[:x] + opts[:y]; end
|
146
|
-
|
149
|
+
|
147
150
|
has_named_parameters :method_with_many_optional_parameters_too, :optional => [ { :x => 1 }, { :y => 2 } ]
|
148
151
|
def method_with_many_optional_parameters_too opts = { }; opts[:x] + opts[:y]; end
|
149
152
|
end
|
@@ -151,11 +154,11 @@ describe "NamedParameters" do
|
|
151
154
|
zoo = Zoo.new
|
152
155
|
zoo.method_with_one_optional_parameter.should eql 1
|
153
156
|
zoo.method_with_one_optional_parameter(:x => 2).should eql 2
|
154
|
-
|
157
|
+
|
155
158
|
zoo.method_with_many_optional_parameters.should eql 3
|
156
159
|
zoo.method_with_many_optional_parameters(:x => 2).should eql 4
|
157
160
|
zoo.method_with_many_optional_parameters(:x => 2, :y => 3).should eql 5
|
158
|
-
|
161
|
+
|
159
162
|
zoo.method_with_many_optional_parameters_too.should eql 3
|
160
163
|
zoo.method_with_many_optional_parameters_too(:x => 2).should eql 4
|
161
164
|
zoo.method_with_many_optional_parameters_too(:x => 2, :y => 3).should eql 5
|
@@ -163,8 +166,10 @@ describe "NamedParameters" do
|
|
163
166
|
|
164
167
|
it "should be able to instrument the class method new" do
|
165
168
|
class Quux
|
166
|
-
has_named_parameters :new, :required => :x
|
167
|
-
|
169
|
+
has_named_parameters :'self.new', :required => :x
|
170
|
+
class << self
|
171
|
+
def new opts = { }; end
|
172
|
+
end
|
168
173
|
def initialize opts = { }; end
|
169
174
|
end
|
170
175
|
lambda { Quux.new }.should raise_error ArgumentError
|
@@ -175,7 +180,7 @@ describe "NamedParameters" do
|
|
175
180
|
|
176
181
|
it "should be able to specify optional parameters using the recognizes method" do
|
177
182
|
class Recognizes
|
178
|
-
recognizes
|
183
|
+
recognizes :x, :y
|
179
184
|
def self.new opts = { }; end
|
180
185
|
def initialize opts = { }; end
|
181
186
|
end
|
@@ -185,10 +190,10 @@ describe "NamedParameters" do
|
|
185
190
|
lambda { Recognizes.new :x => :x, :y => :y }.should_not raise_error
|
186
191
|
lambda { Recognizes.new :z => :z }.should raise_error ArgumentError
|
187
192
|
end
|
188
|
-
|
193
|
+
|
189
194
|
it "should be able to specify required parameters using the recognizes method" do
|
190
195
|
class Required
|
191
|
-
requires
|
196
|
+
requires :x, :y
|
192
197
|
def self.new opts = { }; end
|
193
198
|
def initialize opts = { }; end
|
194
199
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: named-parameters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Juris Galang
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-22 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -58,7 +58,6 @@ extra_rdoc_files:
|
|
58
58
|
- README.md
|
59
59
|
files:
|
60
60
|
- .document
|
61
|
-
- .gitignore
|
62
61
|
- GPL-LICENSE
|
63
62
|
- MIT-LICENSE
|
64
63
|
- README.md
|
@@ -77,8 +76,8 @@ homepage: http://github.com/jurisgalang/named-parameters
|
|
77
76
|
licenses: []
|
78
77
|
|
79
78
|
post_install_message:
|
80
|
-
rdoc_options:
|
81
|
-
|
79
|
+
rdoc_options: []
|
80
|
+
|
82
81
|
require_paths:
|
83
82
|
- lib
|
84
83
|
required_ruby_version: !ruby/object:Gem::Requirement
|