marameters 0.0.0 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a92d21f1146d77f296e63cf36db2f70a2b71318c6d117bb962fc4d4ac34616c
4
- data.tar.gz: 102690432048fb246e14f6bce38ed34d1ac6415ed82a7356ac3f43313bf78eeb
3
+ metadata.gz: 0e9a67405793129c6913e84a4ead90cbc6eda2abbec139f00764a677aa6d30b1
4
+ data.tar.gz: fe3d699a7717e37ae79d07773870cf1137ad0b4b14a761c3eaaa56ed9a4f9fdd
5
5
  SHA512:
6
- metadata.gz: 91efba790017f9d67f5de1513027455a34915822346b6e0e4502dfb6d4e1d0bb4e638342b364108caac35a8598cd18344f6df7d68743107db355cf36eb9470cd
7
- data.tar.gz: 7931c8990397233aac682ca43701b5b90c4d045263abde99c3d52ac800050acbaabea5b96d02e5f0fae687d635894d3d1681d9f0eb856a1cd5f27219c0e8b6cb
6
+ metadata.gz: ded0a8de22a2f67bdb2f308bbfc02db520fb98028b1595825d9e4ab82396b6bdb062a5a602c1df52ced38862963c5b0eb3285cdee586a6934f5f888a6777d313
7
+ data.tar.gz: bc840a326f4116973cda051c23b411f92e74b53e2f704e69adb9536159ef178a16b094c29f52b038dfb17af65be2f26fbe10e7d062da2b5e222bb704895a7793
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -4,14 +4,14 @@
4
4
 
5
5
  = Marameters
6
6
 
7
- Marameters is short for method parameters (i.e. [m]ethod + p[arameters] = marameters) which is
7
+ Marameters is short for method parameters (i.e. `[m]ethod + p[arameters] = marameters`) which is
8
8
  designed to provide additional insight and diagnostics to method parameters. For context, the
9
9
  difference between a method's parameters and arguments is:
10
10
 
11
- * *Parameters*: Represents the _expected_ values to be passed to a method when messaged as defined
12
- when the method is implemented. Example: `def demo(one, two: nil)`.
11
+ * *Parameters*: Represents the _expected_ values to be passed to a method when
12
+ messaged as defined when the method is implemented. Example: `def demo(one, two: nil)`.
13
13
  * *Arguments*: Represents the _actual_ values passed to the method when messaged.
14
- Example: `demo 1, two :2`.
14
+ Example: `demo 1, two: 2`.
15
15
 
16
16
  This gem will help you debug methods or -- more importantly -- aid your workflow when
17
17
  metaprogramming and architecting more sophisticated applications.
@@ -45,50 +45,50 @@ gem "marameters"
45
45
 
46
46
  == Usage
47
47
 
48
- The primary object you'll most likely want to interact with is the `Marameters::Core` class. The
49
- following code snippet will help demonstrate the Object API:
48
+ The primary object you'll want to interact with is the `Marameters::Analyzer` class. To understand
49
+ how to _analyze_ a method's parameters, consider the following demonstration class:
50
50
 
51
51
  [source,ruby]
52
52
  ----
53
53
  class Demo
54
+ def initialize logger: Logger.new(STDOUT)
55
+ @logger = logger
56
+ end
57
+
54
58
  def example one, two = nil, *three, four:, five: nil, **six, &seven
55
- [one, two, three, four, five, six, seven]
59
+ logger.debug [one, two, three, four, five, six, seven]
56
60
  end
57
- end
58
61
 
59
- marameters = Marameters::Core.new Demo.instance_method(:example).parameters
60
-
61
- marameters.empty? # false
62
- marameters.keyword? :one # false
63
- marameters.keyword? :four # true
64
- marameters.keywords # [:four, :five]
65
- marameters.kinds # [:req, :opt, :keyreq, :key, :rest, :keyrest]
66
- marameters.named_single_splat_only? # false
67
- marameters.names # [:one, :two, :four, :five, :three, :six]
68
- marameters.positional? # true
69
- marameters.positionals # [:one, :two]
70
- marameters.to_a # [[:req, :one], [:opt, :two], [:rest, :three], [:keyreq, :four], [:key, :five], [:keyrest, :six], [:block, :seven]]
71
- marameters.unnamed_splats_only? # false
62
+ private
63
+
64
+ attr_reader :logger
65
+ end
72
66
  ----
73
67
 
74
- The `Marameters::Core` delegates to the following classes which you can use individually as well:
68
+ We can then analyze the above `#example` method's parameters as follows:
75
69
 
76
70
  [source,ruby]
77
71
  ----
78
- class Demo
79
- def example one, two = nil, *three, four:, five: nil, **six, &seven
80
- [one, two, three, four, five, six, seven]
81
- end
82
- end
83
-
84
- # Specializes in positional method parameters only.
85
- positional = Marameters::Positional.new Demo.instance_method(:example).parameters
86
-
87
- # Specializes in keyword method parameters only.
88
- keyword = Marameters::Keyword.new Demo.instance_method(:example).parameters
89
-
90
- # Specializes in splatted method parameters only.
91
- splat = Marameters::Splat.new Demo.instance_method(:example).parameters
72
+ analyzer = Marameters::Analyzer.new Demo.instance_method(:example).parameters
73
+
74
+ analyzer.block # :seven
75
+ analyzer.block? # true
76
+ analyzer.empty? # false
77
+ analyzer.keywords # [:four, :five]
78
+ analyzer.keywords? # true
79
+ analyzer.kind?(:keyrest) # true
80
+ analyzer.kinds # [:req, :opt, :rest, :keyreq, :key, :keyrest, :block]
81
+ analyzer.name?(:three) # true
82
+ analyzer.names # [:one, :two, :three, :four, :five, :six, :seven]
83
+ analyzer.only_bare_splats? # false
84
+ analyzer.only_double_splats? # false
85
+ analyzer.only_single_splats? # false
86
+ analyzer.positionals # [:one, :two]
87
+ analyzer.positionals? # true
88
+ analyzer.splats # [:three, :six]
89
+ analyzer.splats? # true
90
+ analyzer.to_a # [[:req, :one], [:opt, :two], [:rest, :three], [:keyreq, :four], [:key, :five], [:keyrest, :six], [:block, :seven]]
91
+ analyzer.to_h # {:req=>:one, :opt=>:two, :rest=>:three, :keyreq=>:four, :key=>:five, :keyrest=>:six, :block=>:seven}
92
92
  ----
93
93
 
94
94
  == Development
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "refinements/arrays"
4
+
5
+ module Marameters
6
+ # Provides analysis of a method's parameters.
7
+ class Analyzer
8
+ using Refinements::Arrays
9
+
10
+ # :reek:TooManyStatements
11
+ def self.of klass, name, collection: []
12
+ method = klass.instance_method name
13
+
14
+ return collection unless method
15
+
16
+ collection << new(method.parameters)
17
+ super_method = method.super_method
18
+ of super_method.owner, super_method.name, collection:
19
+ rescue NameError
20
+ collection
21
+ end
22
+
23
+ def initialize parameters
24
+ @parameters = parameters
25
+ @items = parameters.reduce({}) { |all, (kind, name)| all.merge kind => name }
26
+ end
27
+
28
+ def block = items[:block]
29
+
30
+ def block? = items.key? :block
31
+
32
+ def empty? = items.empty?
33
+
34
+ def keyword_slice collection, keys:
35
+ collection.select { |key| !keys.include?(key) || keywords.include?(key) }
36
+ end
37
+
38
+ def keywords = items.values_at(:keyreq, :key).compress!
39
+
40
+ def keywords? = keywords.any?
41
+
42
+ def kind?(kind) = items.key? kind
43
+
44
+ def kinds = items.keys
45
+
46
+ def name?(name) = items.value? name
47
+
48
+ def names = items.values
49
+
50
+ def only_bare_splats? = (parameters in [[:rest]] | [[:keyrest]] | [[:rest], [:keyrest]])
51
+
52
+ def only_double_splats? = (parameters in [[:keyrest, *]])
53
+
54
+ def only_single_splats? = (parameters in [[:rest, *]])
55
+
56
+ def positionals = items.values_at(:req, :opt).compress!
57
+
58
+ def positionals? = positionals.any?
59
+
60
+ def splats = items.values_at(:rest, :keyrest).compress!
61
+
62
+ def splats? = splats.any?
63
+
64
+ def to_a = parameters
65
+
66
+ def to_h = items
67
+
68
+ private
69
+
70
+ attr_reader :parameters, :items
71
+ end
72
+ end
data/lib/marameters.rb CHANGED
@@ -6,8 +6,4 @@ Zeitwerk::Loader.for_gem.setup
6
6
 
7
7
  # Main namespace.
8
8
  module Marameters
9
- TRANSFORMER = lambda do |parameters, pattern|
10
- parameters.select { |kind, _name| pattern.include? kind }
11
- .reduce({}) { |collection, (kind, name)| collection.merge kind => name }
12
- end
13
9
  end
data/marameters.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "marameters"
5
- spec.version = "0.0.0"
5
+ spec.version = "0.1.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://www.alchemists.io/projects/marameters"
9
- spec.summary = "Provides method parameter introspection."
9
+ spec.summary = "Provides method parameter introspection which is useful when metaprogramming."
10
10
  spec.license = "Hippocratic-2.1"
11
11
 
12
12
  spec.metadata = {
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.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -28,7 +28,7 @@ cert_chain:
28
28
  lkHilIrX69jq8wMPpBhlaw2mRmeSL50Wv5u6xVBvOHhXFSP1crXM95vfLhLyRYod
29
29
  W2A=
30
30
  -----END CERTIFICATE-----
31
- date: 2022-03-06 00:00:00.000000000 Z
31
+ date: 2022-03-11 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: refinements
@@ -70,10 +70,7 @@ files:
70
70
  - LICENSE.adoc
71
71
  - README.adoc
72
72
  - lib/marameters.rb
73
- - lib/marameters/core.rb
74
- - lib/marameters/keyword.rb
75
- - lib/marameters/positional.rb
76
- - lib/marameters/splat.rb
73
+ - lib/marameters/analyzer.rb
77
74
  - marameters.gemspec
78
75
  homepage: https://www.alchemists.io/projects/marameters
79
76
  licenses:
@@ -103,5 +100,5 @@ requirements: []
103
100
  rubygems_version: 3.3.8
104
101
  signing_key:
105
102
  specification_version: 4
106
- summary: Provides method parameter introspection.
103
+ summary: Provides method parameter introspection which is useful when metaprogramming.
107
104
  test_files: []
metadata.gz.sig CHANGED
Binary file
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Marameters
4
- # Provides access to method arguments for meta-programming and/or debugging purposes.
5
- class Core
6
- # Order matters.
7
- DELEGATES = {positional: Positional, keyword: Keyword, splat: Splat}.freeze
8
-
9
- # :reek:TooManyStatements
10
- def self.of klass, name, collection: []
11
- method = klass.instance_method name
12
-
13
- return collection unless method
14
-
15
- collection << new(method.parameters)
16
- super_method = method.super_method
17
- of super_method.owner, super_method.name, collection:
18
- rescue NameError
19
- collection
20
- end
21
-
22
- def initialize parameters, delegates: DELEGATES
23
- @parameters = parameters
24
-
25
- @delegates = delegates.reduce({}) do |accumulator, (key, klass)|
26
- accumulator.merge key => klass.new(parameters)
27
- end
28
- end
29
-
30
- def empty? = parameters.empty?
31
-
32
- def keyword?(name) = keyword.name? name
33
-
34
- def keywords = keyword.names
35
-
36
- def kinds = delegates.values.reduce([]) { |collection, delegate| collection + delegate.kinds }
37
-
38
- def named_single_splat_only? = splat.named_single_only?
39
-
40
- def names = delegates.values.reduce([]) { |collection, delegate| collection + delegate.names }
41
-
42
- def positional? = !positional.empty?
43
-
44
- def positionals = positional.names
45
-
46
- def slice collection, keys:
47
- collection.select { |key| !keys.include?(key) || keyword.names.include?(key) }
48
- end
49
-
50
- def to_a = parameters
51
-
52
- def unnamed_splats_only? = splat.unnamed_only?
53
-
54
- private
55
-
56
- attr_reader :parameters, :delegates
57
-
58
- def keyword = delegates.fetch(__method__)
59
-
60
- def splat = delegates.fetch(__method__)
61
-
62
- def positional = delegates.fetch(__method__)
63
- end
64
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Marameters
4
- # Specializes in providing keyword method parameter information only.
5
- class Keyword
6
- PATTERN = %i[key keyreq].freeze
7
-
8
- def initialize parameters, pattern: PATTERN, transformer: TRANSFORMER
9
- @parameters = parameters
10
- @collection = transformer.call parameters, pattern
11
- end
12
-
13
- def empty? = collection.empty?
14
-
15
- def kinds = collection.keys
16
-
17
- def name?(name) = collection.value? name
18
-
19
- def names = collection.values
20
-
21
- private
22
-
23
- attr_reader :parameters, :collection
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Marameters
4
- # Specializes in providing positional method paratemer information only.
5
- class Positional
6
- PATTERN = %i[req opt].freeze
7
-
8
- def initialize parameters, pattern: PATTERN, transformer: TRANSFORMER
9
- @parameters = parameters
10
- @collection = transformer.call parameters, pattern
11
- end
12
-
13
- def empty? = collection.empty?
14
-
15
- def kinds = collection.keys
16
-
17
- def names = collection.values
18
-
19
- private
20
-
21
- attr_reader :parameters, :collection
22
- end
23
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Marameters
4
- # Specializes in providing passthrough method parameter information only.
5
- class Splat
6
- PATTERN = %i[rest keyrest].freeze
7
-
8
- def initialize parameters, pattern: PATTERN, transformer: TRANSFORMER
9
- @parameters = parameters
10
- @collection = transformer.call parameters, pattern
11
- end
12
-
13
- def empty? = collection.empty?
14
-
15
- def kinds = collection.keys
16
-
17
- def names = collection.values
18
-
19
- def named_double_only? = (parameters in [[:keyrest, *]])
20
-
21
- def named_single_only? = (parameters in [[:rest, *]])
22
-
23
- def unnamed_only? = (parameters in [[:rest]] | [[:keyrest]] | [[:rest], [:keyrest]])
24
-
25
- private
26
-
27
- attr_reader :parameters, :collection
28
- end
29
- end