marameters 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b609969a342c64c1ab5c475f0198bee7f8677d2bb9641234a9f13acbdfd39120
4
- data.tar.gz: 11cdc1166b5c66f13d81558f1691e833d4378ddd4c04c547a0e6b5135e53a1d2
3
+ metadata.gz: 0656ba29b3d12d44f9f34ae3a012542dc3a274712d2cabf8ba153053d1491310
4
+ data.tar.gz: 21e3a15d709561a6c30adb4a212b1193c0d45a2e0f783761719054412a014136
5
5
  SHA512:
6
- metadata.gz: 6a1b20eb861d4ca7b1d821f52e77631dd23a71896973c259235c959e96e81f8e3dafc4bdea64729e758ff4ed0e42b06967a96e27e091f2ddaebb80c8d345fc4e
7
- data.tar.gz: 0d7d78973c128a0281dd868d21ac56a0f742578c82f42531c78408487432ec0af217bfbe103fc0c2c1f6aa95545733df76aeb5d4236072e44df8bf72f6e1c80d
6
+ metadata.gz: 152aa26bb96768bc363f55a7fa43b5aed99f08038ac1bbb4a943a1efdf8b5138ce214b6a4b8012f179f12d00894a44869df6d25d938521712de35a3ab2c6efbd
7
+ data.tar.gz: 620bf72c7c8bbe25b48dc370cee7d3a0e1b03f5df8090c326bc760be1dfb400168d62dac304e55acded56f75da24ca821c4ce04fa9cfb2740ad749434de69fec
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -64,7 +64,6 @@ Marameters.categorize parameters, arguments
64
64
  Marameters.of self, :demo # []
65
65
 
66
66
  probe = Marameters.probe parameters
67
- probe.to_h # {:req=>:one, :opt=>:two, :key=>:three}
68
67
  probe.to_a # [[:req, :one], [:opt, :two], [:key, :three]]
69
68
  probe.positionals # [:one, :two]
70
69
  probe.keywords # [:three]
@@ -72,23 +71,12 @@ probe.block # nil
72
71
 
73
72
  # Marameters::Signature wrapper
74
73
 
75
- Marameters.signature({req: :one, opt: [:two, 2], key: [:three, 3]})
74
+ Marameters.signature({req: :one, opt: [:two, 2], key: [:three, 3]}).to_s
76
75
  # one, two = 2, three: 3
77
76
  ----
78
77
 
79
78
  Read on to learn more about the details on how each of these methods work and the objects they wrap.
80
79
 
81
- === Kinds
82
-
83
- Should you need a list of the kinds of parameters supported, you can use the `KINDS` constant. Example:
84
-
85
- [source,ruby]
86
- ----
87
- Marameters::KINDS # [:req, :opt, :rest, :keyreq, :key, :keyrest, :block]
88
- ----
89
-
90
- All keys are listed in order of precedence.
91
-
92
80
  === Probe
93
81
 
94
82
  The probe allows you to analyze a method's parameters. To understand how, consider the following demonstration class:
@@ -135,7 +123,6 @@ probe.positionals? # true
135
123
  probe.splats # [:three, :six]
136
124
  probe.splats? # true
137
125
  probe.to_a # [[:req, :one], [:opt, :two], [:rest, :three], [:keyreq, :four], [:key, :five], [:keyrest, :six], [:block, :seven]]
138
- probe.to_h # {:req=>:one, :opt=>:two, :rest=>:three, :keyreq=>:four, :key=>:five, :keyrest=>:six, :block=>:seven}
139
126
  ----
140
127
 
141
128
  In contrast the above, we can also probe the `#none` method which has no parameters for a completely
@@ -162,12 +149,11 @@ probe.positionals? # false
162
149
  probe.splats # []
163
150
  probe.splats? # false
164
151
  probe.to_a # []
165
- probe.to_h # {}
166
152
  ----
167
153
 
168
154
  === Categorizer
169
155
 
170
- The categorizer allows you to dynamically build positional, keyword, and block arguments for message passing. This is most valuable when you know the object, method, and arguments while also needing to assemble _and validate_ the arguments are in the right order. Here's a demonstration where {amazing_print_link} (i.e. `ap`) is used to format the output:
156
+ The categorizer allows you to dynamically build positional, keyword, and block arguments for message passing. This is most valuable when you know the object, method, and arguments while also needing to assemble the arguments are in the right order. Here's a demonstration where {amazing_print_link} (i.e. `ap`) is used to format the output:
171
157
 
172
158
  [source,ruby]
173
159
  ----
@@ -198,14 +184,15 @@ end
198
184
 
199
185
  Inspector.call [1, nil, nil, {four: 4}]
200
186
 
201
- # #<Struct:Marameters::Splat:0x00001068
202
- # block = nil,
203
- # keywords = {
204
- # :four => 4
205
- # },
206
- # positionals = [
207
- # 1
208
- # ]
187
+ # #<Struct:Marameters::Splat:0x00021930
188
+ # block = nil,
189
+ # keywords = {
190
+ # :four => 4
191
+ # },
192
+ # positionals = [
193
+ # 1,
194
+ # nil
195
+ # ]
209
196
  # >
210
197
  #
211
198
  # The .test method received the following arguments:
@@ -235,30 +222,30 @@ Inspector.call [1, 2, [98, 99], {four: 4}, {five: 5}, {twenty: 20, thirty: 30},
235
222
 
236
223
  # Output
237
224
 
238
- #<Struct:Marameters::Splat:0x00001068
239
- block = #<Proc:0x000000011b19e300 /snippet:32>,
240
- keywords = {
241
- :four => 4,
242
- :five => 5,
243
- :twenty => 20,
244
- :thirty => 30
245
- },
246
- positionals = [
247
- 1,
248
- 2,
249
- 98,
250
- 99
251
- ]
252
- >
253
-
254
- The .test method received the following arguments:
255
- 1. 1
256
- 2. 2
257
- 3. [98, 99]
258
- 4. 4
259
- 5. 5
260
- 6. {:twenty=>20, :thirty=>30}
261
- 7. #<Proc:0x000000011b19e300 /snippet:32>
225
+ # #<Struct:Marameters::Splat:0x00029cc0
226
+ # block = #<Proc:0x000000010a88cec0 (irb):1>,
227
+ # keywords = {
228
+ # :four => 4,
229
+ # :five => 5,
230
+ # :twenty => 20,
231
+ # :thirty => 30
232
+ # },
233
+ # positionals = [
234
+ # 1,
235
+ # 2,
236
+ # 98,
237
+ # 99
238
+ # ]
239
+ # >
240
+ #
241
+ # The .test method received the following arguments:
242
+ # 1. 1
243
+ # 2. 2
244
+ # 3. [98, 99]
245
+ # 4. 4
246
+ # 5. 5
247
+ # 6. {:twenty=>20, :thirty=>30}
248
+ # 7. #<Proc:0x000000010a88cec0 (irb):1>
262
249
  ----
263
250
 
264
251
  Once again, it is important to keep in mind that the argument positions _must_ align with the parameter positions since the parameters are an array of elements too. For illustration purposes -- and using the above example -- we can compare the parameters to the arguments as follows:
@@ -23,17 +23,16 @@ module Marameters
23
23
  attr_reader :parameters, :model, :record
24
24
 
25
25
  def map arguments
26
- parameters.each.with_index { |pair, index| filter pair, arguments[index], arguments }
26
+ parameters.each.with_index { |pair, index| filter pair, arguments[index] }
27
27
  end
28
28
 
29
- def filter pair, value, arguments
29
+ def filter pair, value
30
30
  case pair
31
- in [:rest] | [:rest, :*] then splat_positionals arguments
32
- in [:keyrest] | [:keyrest, :**] then splat_keywords arguments
33
- in [:block, :&] then forward_block arguments
34
- in [:req, *] then record.positionals.append value
35
- in [:opt, *] then record.positionals.append value if value
31
+ in [:rest] | [:rest, :*] then splat_positional value
32
+ in [:keyrest] | [:keyrest, :**] then record.keywords = Hash value
33
+ in [:req, *] | [:opt, *] then record.positionals.append value
36
34
  in [:rest, *] then record.positionals.append(*value)
35
+ in [:nokey] then nil
37
36
  in [:keyreq, *] | [:key, *] then record.keywords.merge! value if value
38
37
  in [:keyrest, *] then record.keywords.merge!(**value) if value
39
38
  in [:block, *] then record.block = value
@@ -43,19 +42,10 @@ module Marameters
43
42
  raise TypeError, "#{value.inspect} is an invalid #{pair.first.inspect} value."
44
43
  end
45
44
 
46
- def splat_positionals arguments
47
- arguments.reject { |item| item in Hash | Proc }
48
- .flatten
49
- .then { |values| record.positionals.append(*values) }
50
- end
51
-
52
- def splat_keywords arguments
53
- arguments.each { |value| record.keywords.merge! value if value.is_a? Hash }
54
- end
45
+ def splat_positional value
46
+ return unless value
55
47
 
56
- def forward_block arguments
57
- arguments.find { |item| item.is_a? Proc }
58
- .then { |block| record.block = block }
48
+ record.positionals = value.is_a?(Array) ? value : [value]
59
49
  end
60
50
  end
61
51
  end
@@ -7,6 +7,12 @@ module Marameters
7
7
  class Probe
8
8
  using Refinements::Arrays
9
9
 
10
+ CATEGORIES = {
11
+ positionals: %i[req opt],
12
+ keywords: %i[keyreq key],
13
+ splats: %i[rest keyrest]
14
+ }.freeze
15
+
10
16
  def self.of klass, name, collection: []
11
17
  method = klass.instance_method name
12
18
  collection << new(method.parameters)
@@ -16,32 +22,32 @@ module Marameters
16
22
  collection
17
23
  end
18
24
 
19
- def initialize parameters
25
+ attr_reader :keywords, :positionals, :splats
26
+
27
+ def initialize parameters, categories: CATEGORIES
20
28
  @parameters = parameters
21
- @items = parameters.reduce({}) { |all, (kind, name)| all.merge kind => name }
29
+ categories.each { |category, kinds| define_variable category, kinds }
22
30
  end
23
31
 
24
- def block = items[:block]
32
+ def block = parameters.find { |kind, name| break name if kind == :block }
25
33
 
26
- def block? = items.key? :block
34
+ def block? = (parameters in [*, [:block, *]])
27
35
 
28
- def empty? = items.empty?
36
+ def empty? = parameters.empty?
29
37
 
30
38
  def keyword_slice collection, keys:
31
39
  collection.select { |key| !keys.include?(key) || keywords.include?(key) }
32
40
  end
33
41
 
34
- def keywords = items.values_at(:keyreq, :key).compress!
35
-
36
42
  def keywords? = keywords.any?
37
43
 
38
- def kind?(kind) = items.key? kind
44
+ def kind?(value) = parameters.any? { |kind, _name| kind == value }
39
45
 
40
- def kinds = items.keys
46
+ def kinds = parameters.map { |kind, _name| kind }
41
47
 
42
- def name?(name) = items.value? name
48
+ def name?(value) = parameters.any? { |_kind, name| name == value }
43
49
 
44
- def names = items.values
50
+ def names = parameters.map { |_kind, name| name }
45
51
 
46
52
  def only_bare_splats? = (parameters in [[:rest]] | [[:keyrest]] | [[:rest], [:keyrest]])
47
53
 
@@ -49,20 +55,19 @@ module Marameters
49
55
 
50
56
  def only_single_splats? = (parameters in [[:rest, *]])
51
57
 
52
- def positionals = items.values_at(:req, :opt).compress!
53
-
54
58
  def positionals? = positionals.any?
55
59
 
56
- def splats = items.values_at(:rest, :keyrest).compress!
57
-
58
60
  def splats? = splats.any?
59
61
 
60
62
  def to_a = parameters
61
63
 
62
- def to_h = items
63
-
64
64
  private
65
65
 
66
- attr_reader :parameters, :items
66
+ attr_reader :parameters
67
+
68
+ def define_variable category, kinds
69
+ parameters.filter_map { |kind, name| next name if kinds.include? kind }
70
+ .then { |collection| instance_variable_set "@#{category}", collection }
71
+ end
67
72
  end
68
73
  end
data/lib/marameters.rb CHANGED
@@ -6,8 +6,6 @@ Zeitwerk::Loader.for_gem.setup
6
6
 
7
7
  # Main namespace.
8
8
  module Marameters
9
- KINDS = %i[req opt rest keyreq key keyrest block].freeze
10
-
11
9
  def self.categorize(parameters, arguments) = Categorizer.new(parameters).call(arguments)
12
10
 
13
11
  def self.of(...) = Probe.of(...)
data/marameters.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "marameters"
5
- spec.version = "0.7.0"
5
+ spec.version = "0.8.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://www.alchemists.io/projects/marameters"
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marameters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,7 +28,7 @@ cert_chain:
28
28
  CxDe2+VuChj4I1nvIHdu+E6XoEVlanUPKmSg6nddhkKn2gC45Kyzh6FZqnzH/CRp
29
29
  RFE=
30
30
  -----END CERTIFICATE-----
31
- date: 2022-09-01 00:00:00.000000000 Z
31
+ date: 2022-09-03 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: refinements
metadata.gz.sig CHANGED
Binary file