optionalargument 0.3 → 0.4.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: c81bbece17d9283e74017a1de8c36a21014bb3b92c7a3c507c39c67b7323a0dd
4
- data.tar.gz: 70e6ad4b0100e9b562fd661a23a90c7068168c8c75e67e9df6766c4afbbe3a10
3
+ metadata.gz: 7451bf7e4951c73d76695c459fa73c5ba2632b6b1d2b9f48675198ca5965c65c
4
+ data.tar.gz: 7dcbedaa36a7f90b3a2a779decb728546e2240e8cace65a4738bc411ec13379a
5
5
  SHA512:
6
- metadata.gz: 5112ba43adb1f9357b27d374f95b47b89c1388fdd34fd7fd453e7f86a78c91dde27ef8528170bdd0b4e938dc2417e94e09fc76177ca3591b6f24e33ab70464df
7
- data.tar.gz: '018943e8d8e79eaedb261df2573af36e96be2f9bf741673cffd08f521f3ea6d025201c5975667dfa5961a43b706a877e089887399150b7d95144b3b5f05dbbc5'
6
+ metadata.gz: 2b686d514beddcc20776dc40018d0a37e91b56fe974b9b24a5ab2a9fb3db8a3465580a0414b108534a6c136c4b09ad6f5cc151f342a2708b4e01f97474092cf8
7
+ data.tar.gz: 9e15cc648bd73147bfeed6a6853e57ac7467a184f509def7debf67eef94ebce1f559c92981d531d33306c945a581f3d2368ca9532c354ce3745886b4e898dfea
File without changes
data/README.md CHANGED
@@ -1,28 +1,21 @@
1
- optionalargument
2
- =================
1
+ # optionalargument
3
2
 
4
- [![Build Status](https://secure.travis-ci.org/kachick/optionalargument.png)](http://travis-ci.org/kachick/optionalargument)
3
+ ![Build Status](https://github.com/kachick/optionalargument/actions/workflows/test_behaviors.yml/badge.svg?branch=main)
5
4
  [![Gem Version](https://badge.fury.io/rb/optionalargument.png)](http://badge.fury.io/rb/optionalargument)
6
- [![Dependency Status](https://gemnasium.com/kachick/optionalargument.svg)](https://gemnasium.com/kachick/optionalargument)
7
5
 
8
- Description
9
- -----------
6
+ Building method arguments checker with DSL
10
7
 
11
- DSL for method-arguments checker
8
+ ## Usage
12
9
 
13
- Features
14
- --------
10
+ Require Ruby 2.6 or later
15
11
 
16
- * Flexible and readable definitions
17
- * Strict parser for key combinations
18
- * Key compatible for Symbol<->String
19
- * Validate and coerce values
20
- * You can use parsed options as Struct
12
+ Add this line to your application/library's `Gemfile` is needed in basic use-case
21
13
 
22
- Usage
23
- -----
14
+ ```ruby
15
+ gem 'optionalargument', '>= 0.4.0', '< 0.5.0'
16
+ ```
24
17
 
25
- You can mix following features :)
18
+ You can mix following features :)
26
19
  Clean up `DEFUALT_OPTIONS.merge(options)` and annoying validations!
27
20
 
28
21
  ### Parser for arguments
@@ -32,11 +25,11 @@ require 'optionalargument'
32
25
 
33
26
  class Foo
34
27
  def func(options={})
35
- opts = OptionalArgument.parse options do
28
+ opts = OptionalArgument.parse(options) do
36
29
  opt :a, must: true
37
30
  opt :b
38
31
  end
39
-
32
+
40
33
  p opts.a
41
34
  p opts.b?
42
35
  p opts.b
@@ -44,10 +37,10 @@ class Foo
44
37
  end
45
38
 
46
39
  foo = Foo.new
47
- foo.func a: 1 #=> opts.a => 1, opts.b? => false, opts.b => nil
48
- foo.func a: 1, "b" => 2 #=> opts.a => 1, opts.b? => true, opts.b => 2
49
- foo.func "b" => 2 #=> Error (`a` is must, but not passed)
50
- foo.func a:1, c: 3 #=> Error (`c` is not defined)
40
+ foo.func({a: 1}) #=> opts.a => 1, opts.b? => false, opts.b => nil
41
+ foo.func({a: 1, 'b' => 2 })#=> opts.a => 1, opts.b? => true, opts.b => 2
42
+ foo.func({'b' => 2}) #=> Error (`a` is must, but not passed)
43
+ foo.func({a: 1, c: 3}) #=> Error (`c` is not defined)
51
44
  ```
52
45
 
53
46
  ### Key combinations
@@ -62,10 +55,10 @@ OptArg = OptionalArgument.define {
62
55
  opt :e, deprecateds: [:e2, :e3]
63
56
  }
64
57
 
65
- OptArg.parse(a: 1, b: 1) #=> Error: conflict conbination thrown: a, b'
66
- OptArg.parse(c: 1) #=> Error: `c` requires `b` and `d`
67
- OptArg.parse(d2: 1).d3 #=> 1
68
- OptArg.parse(e2: 1).e3 #=> 1 with warning "`e2` is deprecated, use `e`"
58
+ OptArg.parse({a: 1, b: 1}) #=> Error: conflict combination thrown: a, b'
59
+ OptArg.parse({c: 1}) #=> Error: `c` requires `b` and `d`
60
+ OptArg.parse({d2: 1}).d3 #=> 1
61
+ OptArg.parse({e2: 1}).e3 #=> 1 with warning "`e2` is deprecated, use `e`"
69
62
  ```
70
63
 
71
64
  ### Validate and coerce value
@@ -77,11 +70,11 @@ OptArg = OptionalArgument.define {
77
70
  opt :z, adjuster: ->arg{Float arg}
78
71
  }
79
72
 
80
- OptArg.parse x: 5 #=> pass : 5 is sufficient for 3..5
81
- OptArg.parse x: 6 #=> Error: 6 is deficient for 3..5
82
- OptArg.parse y: 5 #=> Error: 5 is deficient for Float
83
- OptArg.parse y: 5.0 #=> pass : 5.0 is sufficient for 3..5 and Float
84
- OptArg.parse(z: '1').z #=> 1.0 : casted under adjuster
73
+ OptArg.parse({x: 5}) #=> pass : 5 is sufficient for 3..5
74
+ OptArg.parse({x: 6}) #=> Error: 6 is deficient for 3..5
75
+ OptArg.parse({y: 5}) #=> Error: 5 is deficient for Float
76
+ OptArg.parse({y: 5.0 }) #=> pass : 5.0 is sufficient for 3..5 and Float
77
+ OptArg.parse({z: '1'}).z #=> 1.0 : casted under adjuster
85
78
  ```
86
79
 
87
80
  ### Handle default values
@@ -92,7 +85,7 @@ OptArg = OptionalArgument.define {
92
85
  opt :b, default: 'This is a default value'
93
86
  }
94
87
 
95
- OptArg.parse(a: 1).b #=> 'This is a default value'
88
+ OptArg.parse({a: 1}).b #=> 'This is a default value'
96
89
  ```
97
90
 
98
91
  ### Switch error
@@ -113,33 +106,10 @@ OptArg = OptionalArgument.define {
113
106
  opt :known, must: true
114
107
  }
115
108
 
116
- opts = OptArg.parse(
117
- {known: 1, unknown: 2},
118
- defined_only: false) #=> pass
119
- ```
120
-
121
- Requirements
122
- -------------
123
-
124
- * Ruby - [2.1 or later](http://travis-ci.org/#!/kachick/optionalargument)
125
-
126
- Install
127
- -------
128
-
129
- ```bash
130
- gem install optionalargument
109
+ OptArg.parse({known: 1, unknown: 2}, defined_only: false) #=> pass
131
110
  ```
132
111
 
133
- Link
134
- ----
135
-
136
- * [code](https://github.com/kachick/optionalargument)
137
- * [API](http://www.rubydoc.info/github/kachick/optionalargument)
138
- * [issues](https://github.com/kachick/optionalargument/issues)
139
-
140
- License
141
- --------
112
+ ## Links
142
113
 
143
- The MIT X11 License
144
- Copyright (c) 2012 Kenichi Kamiya
145
- See MIT-LICENSE for further details.
114
+ * [Repository](https://github.com/kachick/my_new_library)
115
+ * [API documents](https://kachick.github.io/my_new_library/)
@@ -1,8 +1,11 @@
1
1
  # coding: us-ascii
2
+ # frozen_string_literal: true
3
+
2
4
  # optionalargument - Revival Hash options
5
+
3
6
  # Copyright (c) 2012 Kenichi Kamiya
4
7
 
5
8
  require_relative 'optionalargument/version'
6
9
  require_relative 'optionalargument/errors'
7
10
  require_relative 'optionalargument/store'
8
- require_relative 'optionalargument/singleton_class'
11
+ require_relative 'optionalargument/singleton_class'
@@ -1,8 +1,7 @@
1
1
  # coding: us-ascii
2
+ # frozen_string_literal: true
2
3
 
3
4
  module OptionalArgument
4
-
5
5
  class MalformedOptionsError < TypeError; end
6
6
  class KeyConflictError < MalformedOptionsError; end
7
-
8
- end
7
+ end
@@ -1,13 +1,12 @@
1
1
  # coding: us-ascii
2
+ # frozen_string_literal: true
2
3
 
3
4
  module OptionalArgument
4
-
5
5
  class << self
6
-
7
6
  # @yieldreturn [Class] subclass of Store
8
7
  # @return [void] must block given
9
8
  def define(&block)
10
- raise ArgumentError, 'block was not given' unless block_given?
9
+ raise ArgumentError, 'block was not given' unless block
11
10
 
12
11
  Class.new(Store) {
13
12
  _init
@@ -15,14 +14,12 @@ module OptionalArgument
15
14
  _fix
16
15
  }
17
16
  end
18
-
17
+
19
18
  # @see OptionalArgument::Store.parse
20
- def parse(opts, parsing_options={}, &block)
21
- raise ArgumentError, 'block was not given' unless block_given?
22
-
23
- define(&block).parse opts, parsing_options
24
- end
19
+ def parse(opts, **kwargs, &block)
20
+ raise ArgumentError, 'block was not given' unless block
25
21
 
22
+ define(&block).parse(opts, **kwargs)
23
+ end
26
24
  end
27
-
28
25
  end
@@ -1,18 +1,17 @@
1
1
  # coding: us-ascii
2
+ # frozen_string_literal: true
2
3
 
3
4
  require_relative 'store/singleton_class'
4
5
 
5
6
  module OptionalArgument
6
-
7
7
  # @note
8
8
  # * Don't include Enumerable
9
9
  # "To be Enumerable" is not necessary for this class.
10
10
  # Because main role is just to hold options.
11
11
  #
12
12
  # * Depends only `/\A_+func_*\z/` on implementing for this class.
13
- # Because `func` is keeped for public API of options.
13
+ # Because `func` is kept for public API of options.
14
14
  class Store
15
-
16
15
  alias_method :__class__, :class
17
16
 
18
17
  alias_method :_to_enum, :to_enum
@@ -26,7 +25,7 @@ module OptionalArgument
26
25
  # @param name [Symbol, String, #to_sym]
27
26
  # @return [Symbol]
28
27
  def autonym_for_name(name)
29
- __class__.autonym_for_name name
28
+ __class__.autonym_for_name(name)
30
29
  end
31
30
 
32
31
  alias_method :_autonym_for_name, :autonym_for_name
@@ -34,19 +33,17 @@ module OptionalArgument
34
33
 
35
34
  # @param name [Symbol, String, #to_sym]
36
35
  def [](name)
37
- @pairs[_autonym_for_name name]
36
+ @pairs[_autonym_for_name(name)]
38
37
  end
39
38
 
40
39
  # @param name [Symbol, String, #to_sym]
41
40
  def with?(name)
42
- @pairs.has_key? _autonym_for_name(name)
41
+ @pairs.key?(_autonym_for_name(name))
43
42
  end
44
43
 
45
- alias_method :has_key?, :with?
46
-
47
44
  # @return [String]
48
45
  def inspect
49
- "#<optargs: #{@pairs.map{|k, v|"#{k}=#{v.inspect}"}.join(', ')}>"
46
+ "#<optargs: #{@pairs.map { |k, v| "#{k}=#{v.inspect}" }.join(', ')}>"
50
47
  end
51
48
 
52
49
  alias_method :to_s, :inspect
@@ -56,8 +53,8 @@ module OptionalArgument
56
53
  # @yieldreturn [self]
57
54
  # @return [Enumerator]
58
55
  def each_pair(&block)
59
- return _to_enum(__method__) { @pairs.size } unless block_given?
60
-
56
+ return _to_enum(__method__) { @pairs.size } unless block
57
+
61
58
  @pairs.each_pair(&block)
62
59
  self
63
60
  end
@@ -73,7 +70,7 @@ module OptionalArgument
73
70
  end
74
71
 
75
72
  def eql?(other)
76
- other.instance_of?(__class__) && (other._pairs.eql? @pairs)
73
+ other.instance_of?(__class__) && other._pairs.eql?(@pairs)
77
74
  end
78
75
 
79
76
  # @return [Boolean]
@@ -88,7 +85,5 @@ module OptionalArgument
88
85
  def _pairs
89
86
  @pairs
90
87
  end
91
-
92
88
  end
93
-
94
89
  end
@@ -1,506 +1,473 @@
1
1
  # coding: us-ascii
2
+ # frozen_string_literal: true
2
3
 
3
- require 'keyvalidatable'
4
4
  require 'validation'
5
5
 
6
- module OptionalArgument; class Store
6
+ module OptionalArgument
7
+ class Store
8
+ extend Validation::Condition
9
+ extend Validation::Adjustment
7
10
 
8
- extend Validation::Condition
9
- extend Validation::Adjustment
11
+ # Store's singleton class should behave as builder & parser
12
+ class << self
13
+ private :new
10
14
 
11
- # Store's singleton class should behave as builder & parser
12
- class << self
15
+ # @group Specific Constructor
13
16
 
14
- private :new
17
+ # @param [Boolean] defined_only
18
+ # @param [Exception] exception
19
+ # @return [Store] instance of a Store's subclass
20
+ def parse(options, defined_only: true, exception: nil)
21
+ begin
22
+ unless options.respond_to?(:each_pair)
23
+ raise MalformedOptionsError, 'options must be key-value pairs'
24
+ end
15
25
 
16
- # @group Specific Constructor
26
+ autonym_hash = _autonym_hash_for(options, defined_only)
27
+ _scan_hash!(autonym_hash)
17
28
 
18
- DEFAULT_PARSE_OPTIONS = {
19
- defined_only: true,
20
- exception: nil
21
- }.freeze
22
-
23
- private_constant :DEFAULT_PARSE_OPTIONS
29
+ new(autonym_hash)
30
+ rescue MalformedOptionsError, Validation::InvalidError => err
31
+ if replacement = exception
32
+ raise replacement.new, err
33
+ else
34
+ raise err
35
+ end
36
+ end
37
+ end
24
38
 
25
- # @param options [Hash, Struct, #each_pair]
26
- # @option options [Boolean] :defined_only
27
- # @option options [Exception] :exception
28
- # @param parsing_options [Hash]
29
- # @return [Store] instance of a Store's subclass
30
- def parse(options, parsing_options={})
31
- parsing_options = DEFAULT_PARSE_OPTIONS.merge parsing_options
32
- KeyValidatable.validate_keys parsing_options,
33
- must: [:defined_only, :exception]
39
+ alias_method :for_options, :parse
40
+ alias_method :for_pairs, :parse
34
41
 
35
- begin
36
- unless options.respond_to? :each_pair
37
- raise MalformedOptionsError, 'options must be key-value pairs'
38
- end
42
+ # @endgroup
39
43
 
40
- autonym_hash = _autonym_hash_for options, parsing_options.fetch(:defined_only)
41
- _scan_hash! autonym_hash
44
+ # @group Access option names
42
45
 
43
- new autonym_hash
44
- rescue MalformedOptionsError, Validation::InvalidError => err
45
- if replacemet = parsing_options.fetch(:exception)
46
- raise replacemet.new, err
47
- else
48
- raise err
49
- end
46
+ # @param name [Symbol, String, #to_sym]
47
+ # @return [Symbol]
48
+ def autonym_for_name(name)
49
+ @names.fetch(name.to_sym)
50
50
  end
51
- end
52
-
53
- alias_method :for_options, :parse
54
- alias_method :for_pairs, :parse
55
-
56
- # @endgroup
57
-
58
- # @group Access option names
59
-
60
- # @param name [Symbol, String, #to_sym]
61
- # @return [Symbol]
62
- def autonym_for_name(name)
63
- @names.fetch name.to_sym
64
- end
65
51
 
66
- alias_method :autonym_for, :autonym_for_name
67
-
68
- # @return [Array<Symbol>] - autonym, autonym, ...
69
- def autonyms
70
- @names.values.uniq
71
- end
52
+ alias_method :autonym_for, :autonym_for_name
72
53
 
73
- # @return [Array<Symbol>]
74
- def members
75
- @names.keys
76
- end
54
+ # @return [Array<Symbol>] - autonym, autonym, ...
55
+ def autonyms
56
+ @names.values.uniq
57
+ end
77
58
 
78
- # @return [Array<Symbol>]
79
- def aliases
80
- @names.each_key.select{|name|aliased? name}
81
- end
59
+ # @return [Array<Symbol>]
60
+ def members
61
+ @names.keys
62
+ end
82
63
 
83
- # @return [Array<Symbol>]
84
- def deprecateds
85
- @deprecateds.dup
86
- end
64
+ # @return [Array<Symbol>]
65
+ def aliases
66
+ @names.each_key.select { |name| aliased?(name) }
67
+ end
87
68
 
88
- # @param name [Symbol, String, #to_sym]
89
- def autonym?(name)
90
- @names.has_value? name.to_sym
91
- end
69
+ # @return [Array<Symbol>]
70
+ def deprecateds
71
+ @deprecateds.dup
72
+ end
92
73
 
93
- # @param name [Symbol, String, #to_sym]
94
- def member?(name)
95
- @names.has_key? name.to_sym
96
- end
74
+ # @param name [Symbol, String, #to_sym]
75
+ def autonym?(name)
76
+ @names.value?(name.to_sym)
77
+ end
97
78
 
98
- # @param name [Symbol, String, #to_sym]
99
- def aliased?(name)
100
- member?(name) && !autonym?(name) && !deprecated?(name)
101
- end
79
+ # @param name [Symbol, String, #to_sym]
80
+ def member?(name)
81
+ @names.key?(name.to_sym)
82
+ end
102
83
 
103
- # @param name [Symbol, String, #to_sym]
104
- def deprecated?(name)
105
- @deprecateds.include? name.to_sym
106
- end
84
+ # @param name [Symbol, String, #to_sym]
85
+ def aliased?(name)
86
+ member?(name) && !autonym?(name) && !deprecated?(name)
87
+ end
107
88
 
108
- # @param name [Symbol, String, #to_sym]
109
- def has_default?(name)
110
- member?(name) && @default_values.has_key?(autonym_for_name(name))
111
- end
89
+ # @param name [Symbol, String, #to_sym]
90
+ def deprecated?(name)
91
+ @deprecateds.include?(name.to_sym)
92
+ end
112
93
 
113
- # @param name [Symbol, String, #to_sym]
114
- def has_condition?(name)
115
- member?(name) && @conditions.has_key?(autonym_for_name(name))
116
- end
94
+ # @param name [Symbol, String, #to_sym]
95
+ def default?(name)
96
+ member?(name) && @default_values.key?(autonym_for_name(name))
97
+ end
117
98
 
118
- # @param name [Symbol, String, #to_sym]
119
- def has_adjuster?(name)
120
- member?(name) && @adjusters.has_key?(autonym_for_name(name))
121
- end
99
+ # @param name [Symbol, String, #to_sym]
100
+ def condition?(name)
101
+ member?(name) && @conditions.key?(autonym_for_name(name))
102
+ end
122
103
 
123
- # for debug
124
- # @return [Hash] - autonym/alias/deprecated => autonym, ...
125
- def names_with_autonym
126
- @names.dup
127
- end
104
+ # @param name [Symbol, String, #to_sym]
105
+ def adjuster?(name)
106
+ member?(name) && @adjusters.key?(autonym_for_name(name))
107
+ end
128
108
 
129
- # @endgroup
109
+ # for debug
110
+ # @return [Hash] - autonym/alias/deprecated => autonym, ...
111
+ def names_with_autonym
112
+ @names.dup
113
+ end
130
114
 
131
- private
115
+ # @endgroup
132
116
 
133
- # @group Build and Fix Class's structure - Inner API
134
-
135
- # @return [nil]
136
- def _init
137
- @names = {} # {autonym/alias/deprecated => autonym, ...}
138
- @must_autonyms = [] # [autonym, autonym, ...]
139
- @conflict_autonym_sets = [] # [[*autonyms], [*autonyms], ...]
140
- @requirements = {} # {autonym => [*requirements], ...]
141
- @deprecateds = [] # [deprecated, deprecated, ...]
142
- @default_values = {} # {autonym => value, ...}
143
- @conditions = {} # {autonym => condiiton, ...}
144
- @adjusters = {} # {autonym => adjuster, ...}
117
+ private
145
118
 
146
- nil
147
- end
119
+ # @group Build and Fix Class's structure - Inner API
148
120
 
149
- # @return [nil]
150
- def _fix
151
- raise 'no assigned members yet' if @names.empty?
121
+ # @return [nil]
122
+ def _init
123
+ @names = {} # {autonym/alias/deprecated => autonym, ...}
124
+ @must_autonyms = [] # [autonym, autonym, ...]
125
+ @conflict_autonym_sets = [] # [[*autonyms], [*autonyms], ...]
126
+ @requirements = {} # {autonym => [*requirements], ...]
127
+ @deprecateds = [] # [deprecated, deprecated, ...]
128
+ @default_values = {} # {autonym => value, ...}
129
+ @conditions = {} # {autonym => condition, ...}
130
+ @adjusters = {} # {autonym => adjuster, ...}
152
131
 
153
- instance_variables.each do |var|
154
- instance_variable_get(var).freeze
132
+ nil
155
133
  end
156
134
 
157
- _check_requirements
158
-
159
- nil
160
- end
135
+ # @return [nil]
136
+ def _fix
137
+ raise 'no assigned members yet' if @names.empty?
161
138
 
162
- # @endgroup
163
-
164
- # @group Define options
165
-
166
- DEFAULT_ADD_OPT_OPTIONS = {
167
- must: false,
168
- aliases: [].freeze,
169
- deprecateds: [].freeze,
170
- requirements: [].freeze
171
- }.freeze
172
-
173
- private_constant :DEFAULT_ADD_OPT_OPTIONS
174
-
175
- # @param autonym [Symbol, String, #to_sym]
176
- # @param options [Hash]
177
- # @option options [Boolean] :must
178
- # @option options :default
179
- # @option options [Array<Symbol, String, #to_sym>] :aliases
180
- # @option options [Array<Symbol, String, #to_sym>] :deprecateds
181
- # @option options [Array<Symbol, String, #to_sym>] :requirements
182
- # @option options [#===] :condition
183
- # @option options [#call] :adjuster
184
- # @return [nil]
185
- def add_option(autonym, options={})
186
- autonym = autonym.to_sym
187
- options = DEFAULT_ADD_OPT_OPTIONS.merge options
188
- KeyValidatable.validate_keys(
189
- options,
190
- must: [:must, :aliases, :deprecateds, :requirements],
191
- let: [:default, :condition, :adjuster]
192
- )
193
-
194
- if options.has_key? :condition
195
- _add_condition autonym, options.fetch(:condition)
196
- end
197
-
198
- if options.has_key? :adjuster
199
- _add_adjuster autonym, options.fetch(:adjuster)
200
- end
201
-
202
- if options.fetch :must
203
- if options.has_key? :default
204
- raise KeyConflictError, '"must" conflic with "default"'
139
+ instance_variables.each do |var|
140
+ instance_variable_get(var).freeze
205
141
  end
206
-
207
- _add_must(autonym)
208
- end
209
142
 
210
- if options.has_key? :default
211
- _add_default autonym, options.fetch(:default)
143
+ _check_requirements
144
+
145
+ nil
212
146
  end
213
147
 
214
- _add_requirements autonym, options.fetch(:requirements)
148
+ # @endgroup
215
149
 
216
- deprecateds = options.fetch :deprecateds
150
+ # @group Define options
217
151
 
218
- _add_deprecated(*deprecateds)
152
+ # @param [Symbol, String, #to_sym] autonym
153
+ # @param [Boolean] must
154
+ # @param [#===] condition
155
+ # @param [Array<Symbol, String, #to_sym>] aliases
156
+ # @param [Array<Symbol, String, #to_sym>] deprecateds
157
+ # @param [Array<Symbol, String, #to_sym>] requirements
158
+ # @param [#call] adjuster
159
+ # @return [void]
160
+ def add_option(autonym, condition: nil, adjuster: nil, must: false, default: nil, requirements: [].freeze, deprecateds: [].freeze, aliases: [].freeze)
161
+ autonym = autonym.to_sym
219
162
 
220
- [autonym, *options.fetch(:aliases), *deprecateds].each do |name|
221
- _add_member autonym, name.to_sym
222
- end
163
+ if condition
164
+ _add_condition(autonym, condition)
165
+ end
223
166
 
224
- nil
225
- end
167
+ if adjuster
168
+ _add_adjuster(autonym, adjuster)
169
+ end
226
170
 
227
- alias_method :opt, :add_option
228
- alias_method :on, :add_option
229
-
230
- # @param autonym1 [Symbol, String, #to_sym]
231
- # @param autonym2 [Symbol, String, #to_sym]
232
- # @param autonyms [Symbol, String, #to_sym]
233
- # @return [nil]
234
- def add_conflict(autonym1, autonym2, *autonyms)
235
- autonyms = [autonym1, autonym2, *autonyms].map(&:to_sym)
236
- raise ArgumentError unless autonyms == autonyms.uniq
237
- not_autonyms = (autonyms - @names.values)
238
- unless not_autonyms.empty?
239
- raise ArgumentError, "contain not autonym: #{not_autonyms.join(', ')}"
240
- end
241
- raise if @conflict_autonym_sets.include? autonyms
242
-
243
- @conflict_autonym_sets << autonyms
244
- nil
245
- end
171
+ if must
172
+ unless default.nil?
173
+ raise KeyConflictError, '"must" conflict with "default"'
174
+ end
246
175
 
247
- alias_method :conflict, :add_conflict
176
+ _add_must(autonym)
177
+ end
248
178
 
249
- # @endgroup
179
+ unless default.nil?
180
+ _add_default(autonym, default)
181
+ end
250
182
 
251
- # @group Define options - Inner API
183
+ _add_requirements(autonym, requirements)
252
184
 
253
- # if `_func autonym [Symbol]` requires a coreced symbol.
254
- # Don't pass [String, #to_str].
185
+ _add_deprecated(*deprecateds)
255
186
 
256
- # @param _name [Symbol]
257
- # @return [nil]
258
- def _def_instance_methods(_name)
259
- autonym = autonym_for_name _name
260
- fetcher = :"fetch_by_#{_name}"
187
+ [autonym, *aliases, *deprecateds].each do |name|
188
+ _add_member(autonym, name.to_sym)
189
+ end
261
190
 
262
- define_method fetcher do
263
- self[autonym]
191
+ nil
264
192
  end
265
-
266
- alias_method _name, fetcher
267
193
 
268
- with_predicator = :"with_#{_name}?"
194
+ alias_method :opt, :add_option
195
+ alias_method :on, :add_option
196
+
197
+ # @param autonym1 [Symbol, String, #to_sym]
198
+ # @param autonym2 [Symbol, String, #to_sym]
199
+ # @param autonyms [Symbol, String, #to_sym]
200
+ # @return [nil]
201
+ def add_conflict(autonym1, autonym2, *autonyms)
202
+ autonyms = [autonym1, autonym2, *autonyms].map(&:to_sym)
203
+ raise ArgumentError unless autonyms == autonyms.uniq
269
204
 
270
- define_method with_predicator do
271
- with? autonym
205
+ not_autonyms = (autonyms - @names.values)
206
+ unless not_autonyms.empty?
207
+ raise ArgumentError, "contain not autonym: #{not_autonyms.join(', ')}"
208
+ end
209
+ raise if @conflict_autonym_sets.include?(autonyms)
210
+
211
+ @conflict_autonym_sets << autonyms
212
+ nil
272
213
  end
273
214
 
274
- predicator = :"#{_name}?"
275
- alias_method predicator, with_predicator
215
+ alias_method :conflict, :add_conflict
276
216
 
277
- overrides = [_name, fetcher, with_predicator, predicator].select{|callee|
278
- Store.method_defined?(callee) || Store.private_method_defined?(callee)
279
- }
217
+ # @endgroup
280
218
 
281
- unless overrides.empty?
282
- warn "override methods: #{overrides.join(', ')}"
283
- end
219
+ # @group Define options - Inner API
284
220
 
285
- nil
286
- end
221
+ # if `_func autonym [Symbol]` requires a coerced symbol.
222
+ # Don't pass [String, #to_str].
287
223
 
288
- # @param condition [#===]
289
- def _valid?(condition, value)
290
- condition === value
291
- end
224
+ # @param name [Symbol]
225
+ # @return [nil]
226
+ def _def_instance_methods(name)
227
+ autonym = autonym_for_name(name)
228
+ fetcher = :"fetch_by_#{name}"
292
229
 
293
- # @param autonym [Symbol]
294
- # @return [value]
295
- def _validate_value(autonym, value)
296
- if has_adjuster? autonym
297
- adjuster = @adjusters.fetch autonym
298
- begin
299
- value = adjuster.call value
300
- rescue Exception => err
301
- raise Validation::InvalidAdjustingError, err
230
+ define_method(fetcher) do
231
+ self[autonym]
302
232
  end
303
- end
304
233
 
305
- if has_condition? autonym
306
- condition = @conditions.fetch(autonym)
307
-
308
- unless _valid? condition, value
309
- raise Validation::InvalidWritingError,
310
- "#{value.inspect} is deficient for #{condition}"
234
+ alias_method(name, fetcher)
235
+
236
+ with_predicator = :"with_#{name}?"
237
+
238
+ define_method(with_predicator) do
239
+ with?(autonym)
240
+ end
241
+
242
+ predicator = :"#{name}?"
243
+ alias_method(predicator, with_predicator)
244
+
245
+ overrides = [name, fetcher, with_predicator, predicator].select { |callee|
246
+ Store.method_defined?(callee) || Store.private_method_defined?(callee)
247
+ }
248
+
249
+ unless overrides.empty?
250
+ warn("override methods: #{overrides.join(', ')}")
311
251
  end
252
+
253
+ nil
312
254
  end
313
255
 
314
- value
315
- end
256
+ # @param condition [#===]
257
+ def _valid?(condition, value)
258
+ condition === value
259
+ end
316
260
 
317
- # @param autonym [Symbol]
318
- # @return [autonym]
319
- def _add_must(autonym)
320
- @must_autonyms << autonym
321
- end
261
+ # @param autonym [Symbol]
262
+ # @return [value]
263
+ def _validate_value(autonym, value)
264
+ if adjuster?(autonym)
265
+ adjuster = @adjusters.fetch(autonym)
266
+ begin
267
+ value = adjuster.call(value)
268
+ rescue Exception => err
269
+ raise Validation::InvalidAdjustingError, err
270
+ end
271
+ end
322
272
 
323
- # @param names [Array<Symbol>]
324
- # @return [nil]
325
- def _add_deprecated(*names)
326
- @deprecateds.concat names
327
- nil
328
- end
273
+ if condition?(autonym)
274
+ condition = @conditions.fetch(autonym)
329
275
 
330
- # @param autonym [Symbol]
331
- # @param name [Symbol]
332
- # @return [name]
333
- def _add_member(autonym, name)
334
- if member? name
335
- raise NameError, "already defined the name: #{name}"
276
+ unless _valid?(condition, value)
277
+ raise Validation::InvalidWritingError,
278
+ "#{value.inspect} is deficient for #{condition}"
279
+ end
280
+ end
281
+
282
+ value
336
283
  end
337
-
338
- @names[name] = autonym
339
- _def_instance_methods name
340
- end
341
284
 
342
- # @param autonym [Symbol]
343
- # @param requirements [Array<Symbol, String, #to_sym>]
344
- # @return [nil]
345
- def _add_requirements(autonym, requirements)
346
- unless requirements.kind_of?(Array) && requirements.all?{|name|name.respond_to?(:to_sym)}
347
- raise ArgumentError, "`requirements` requires to be Array<Symbol, String>"
285
+ # @param autonym [Symbol]
286
+ # @return [autonym]
287
+ def _add_must(autonym)
288
+ @must_autonyms << autonym
348
289
  end
349
290
 
350
- @requirements[autonym] = requirements.map(&:to_sym).uniq
351
- nil
352
- end
291
+ # @param names [Array<Symbol>]
292
+ # @return [nil]
293
+ def _add_deprecated(*names)
294
+ @deprecateds.concat(names)
295
+ nil
296
+ end
353
297
 
354
- # @param autonym [Symbol]
355
- # @return [value]
356
- def _add_default(autonym, value)
357
- @default_values[autonym] = value
358
- end
298
+ # @param autonym [Symbol]
299
+ # @param name [Symbol]
300
+ # @return [name]
301
+ def _add_member(autonym, name)
302
+ if member?(name)
303
+ raise NameError, "already defined the name: #{name}"
304
+ end
359
305
 
360
- # @param autonym [Symbol]
361
- # @param condition [#===]
362
- # @return [condition]
363
- def _add_condition(autonym, condition)
364
- unless condition.respond_to? :===
365
- raise TypeError, "#{condition.inspect} is wrong object for condition"
306
+ @names[name] = autonym
307
+ _def_instance_methods(name)
366
308
  end
367
309
 
368
- @conditions[autonym] = condition
369
- end
310
+ # @param autonym [Symbol]
311
+ # @param requirements [Array<Symbol, String, #to_sym>]
312
+ # @return [nil]
313
+ def _add_requirements(autonym, requirements)
314
+ unless requirements.kind_of?(Array) && requirements.all? { |name| name.respond_to?(:to_sym) }
315
+ raise ArgumentError, '`requirements` requires to be Array<Symbol, String>'
316
+ end
370
317
 
371
- # @param autonym [Symbol]
372
- # @param adjuster [#call]
373
- # @return [adjuster]
374
- def _add_adjuster(autonym, adjuster)
375
- unless adjuster.respond_to? :call
376
- raise TypeError, "#{adjuster.inspect} is wrong object for adjuster"
318
+ @requirements[autonym] = requirements.map(&:to_sym).uniq
319
+ nil
377
320
  end
378
321
 
379
- @adjusters[autonym] = adjuster
380
- end
322
+ # @param autonym [Symbol]
323
+ # @return [value]
324
+ def _add_default(autonym, value)
325
+ @default_values[autonym] = value
326
+ end
381
327
 
382
- # @param autonym_hash [Hash]
383
- # @return [autonym_hash]
384
- def _scan_hash!(autonym_hash)
385
- recieved_autonyms = autonym_hash.keys.map{|key|autonym_for_name key}
386
- _validate_autonym_combinations(*recieved_autonyms)
387
- autonym_hash.update _default_pairs_for(*(autonyms - recieved_autonyms))
388
- autonym_hash
389
- end
328
+ # @param autonym [Symbol]
329
+ # @param condition [#===]
330
+ # @return [condition]
331
+ def _add_condition(autonym, condition)
332
+ unless condition.respond_to?(:===)
333
+ raise TypeError, "#{condition.inspect} is wrong object for condition"
334
+ end
390
335
 
391
- # @param options [#each_pair]
392
- # @param defined_only [Boolean]
393
- # @return [Hash]
394
- def _autonym_hash_for(options, defined_only)
395
- hash = {}
396
-
397
- options.each_pair do |key, value|
398
- key = key.to_sym
399
-
400
- if member? key
401
- autonym = autonym_for_name key
402
- raise KeyConflictError, key if hash.has_key? autonym
403
-
404
- if deprecated? key
405
- warn "`#{key}` is deprecated, use `#{autonym}`"
406
- end
336
+ @conditions[autonym] = condition
337
+ end
407
338
 
408
- hash[autonym] = _validate_value autonym, value
409
- else
410
- if defined_only
411
- raise MalformedOptionsError, %Q!unknown defined name "#{key}"!
412
- end
339
+ # @param autonym [Symbol]
340
+ # @param adjuster [#call]
341
+ # @return [adjuster]
342
+ def _add_adjuster(autonym, adjuster)
343
+ unless adjuster.respond_to?(:call)
344
+ raise TypeError, "#{adjuster.inspect} is wrong object for adjuster"
413
345
  end
346
+
347
+ @adjusters[autonym] = adjuster
414
348
  end
415
349
 
416
- hash
417
- end
350
+ # @param autonym_hash [Hash]
351
+ # @return [autonym_hash]
352
+ def _scan_hash!(autonym_hash)
353
+ received_autonyms = autonym_hash.keys.map { |key| autonym_for_name(key) }
354
+ _validate_autonym_combinations(*received_autonyms)
355
+ autonym_hash.update(_default_pairs_for(*(autonyms - received_autonyms)))
356
+ autonym_hash
357
+ end
418
358
 
419
- # @param recieved_autonyms [Array<Symbol>]
420
- # @raise [MalformedOptionsError, KeyConflictError] if invalid autonym combinations
421
- # @return [nil]
422
- def _validate_autonym_combinations(*recieved_autonyms)
423
- _validate_shortage_keys(*recieved_autonyms)
424
- _validate_requirements(*recieved_autonyms)
425
- _validate_conflicts(*recieved_autonyms)
426
- nil
427
- end
359
+ # @param options [#each_pair]
360
+ # @param defined_only [Boolean]
361
+ # @return [Hash]
362
+ def _autonym_hash_for(options, defined_only)
363
+ hash = {}
364
+
365
+ options.each_pair do |key, value|
366
+ key = key.to_sym
367
+
368
+ if member?(key)
369
+ autonym = autonym_for_name(key)
370
+ raise KeyConflictError, key if hash.key?(autonym)
428
371
 
429
- # @param recieved_autonyms [Array<Symbol>]
430
- # @raise [MalformedOptionsError]
431
- # @return [nil]
432
- def _validate_shortage_keys(*recieved_autonyms)
433
- shortage_keys = @must_autonyms - recieved_autonyms
434
-
435
- unless shortage_keys.empty?
436
- raise MalformedOptionsError,
437
- "shortage option parameter: #{shortage_keys.join(', ')}"
372
+ if deprecated?(key)
373
+ warn("`#{key}` is deprecated, use `#{autonym}`")
374
+ end
375
+
376
+ hash[autonym] = _validate_value(autonym, value)
377
+ else
378
+ if defined_only
379
+ raise MalformedOptionsError, %Q!unknown defined name "#{key}"!
380
+ end
381
+ end
382
+ end
383
+
384
+ hash
438
385
  end
439
386
 
440
- nil
441
- end
387
+ # @param received_autonyms [Array<Symbol>]
388
+ # @raise [MalformedOptionsError, KeyConflictError] if invalid autonym combinations
389
+ # @return [nil]
390
+ def _validate_autonym_combinations(*received_autonyms)
391
+ _validate_shortage_keys(*received_autonyms)
392
+ _validate_requirements(*received_autonyms)
393
+ _validate_conflicts(*received_autonyms)
394
+ nil
395
+ end
396
+
397
+ # @param received_autonyms [Array<Symbol>]
398
+ # @raise [MalformedOptionsError]
399
+ # @return [nil]
400
+ def _validate_shortage_keys(*received_autonyms)
401
+ shortage_keys = @must_autonyms - received_autonyms
442
402
 
443
- # @param recieved_autonyms [Array<Symbol>]
444
- # @raise [MalformedOptionsError]
445
- # @return [nil]
446
- def _validate_requirements(*recieved_autonyms)
447
- recieved_autonyms.each do |autonym|
448
- shortage_keys = @requirements.fetch(autonym) - recieved_autonyms
449
403
  unless shortage_keys.empty?
450
404
  raise MalformedOptionsError,
451
- "shortage option parameter for #{autonym}: #{shortage_keys.join(', ')}"
405
+ "shortage option parameter: #{shortage_keys.join(', ')}"
452
406
  end
453
- end
454
407
 
455
- nil
456
- end
408
+ nil
409
+ end
457
410
 
458
- # @param recieved_autonyms [Array<Symbol>]
459
- # @raise [KeyConflictError]
460
- # @return [nil]
461
- def _validate_conflicts(*recieved_autonyms)
462
- conflicts = @conflict_autonym_sets.find{|conflict_autonym_set|
463
- (conflict_autonym_set - recieved_autonyms).empty?
464
- }
411
+ # @param received_autonyms [Array<Symbol>]
412
+ # @raise [MalformedOptionsError]
413
+ # @return [nil]
414
+ def _validate_requirements(*received_autonyms)
415
+ received_autonyms.each do |autonym|
416
+ shortage_keys = @requirements.fetch(autonym) - received_autonyms
417
+ unless shortage_keys.empty?
418
+ raise MalformedOptionsError,
419
+ "shortage option parameter for #{autonym}: #{shortage_keys.join(', ')}"
420
+ end
421
+ end
465
422
 
466
- if conflicts
467
- raise KeyConflictError,
468
- "conflict conbination thrown: #{conflicts.join(', ')}"
423
+ nil
469
424
  end
470
425
 
471
- nil
472
- end
426
+ # @param received_autonyms [Array<Symbol>]
427
+ # @raise [KeyConflictError]
428
+ # @return [nil]
429
+ def _validate_conflicts(*received_autonyms)
430
+ conflicts = @conflict_autonym_sets.find { |conflict_autonym_set|
431
+ (conflict_autonym_set - received_autonyms).empty?
432
+ }
473
433
 
474
- # @param autonyms [Array<Symbol>]
475
- # @return [Hash] autonym => default_value
476
- def _default_pairs_for(*autonyms)
477
- {}.tap {|h|
478
- autonyms.each do |autonym|
479
- if has_default? autonym
480
- h[autonym] = _validate_value autonym, @default_values.fetch(autonym)
481
- end
434
+ if conflicts
435
+ raise KeyConflictError,
436
+ "conflict combination thrown: #{conflicts.join(', ')}"
482
437
  end
483
- }
484
- end
485
438
 
486
- # @return [nil]
487
- def _check_requirements
488
- @requirements.each_pair do |autonym, names|
489
- names.map!{|name|
490
- if member? name
491
- autonym_for_name name
492
- else
493
- raise ArgumentError,
494
- "`#{autonym}` with invalid requirements `#{names}`"
439
+ nil
440
+ end
441
+
442
+ # @param autonyms [Array<Symbol>]
443
+ # @return [Hash] autonym => default_value
444
+ def _default_pairs_for(*autonyms)
445
+ {}.tap { |h|
446
+ autonyms.each do |autonym|
447
+ if default?(autonym)
448
+ h[autonym] = _validate_value(autonym, @default_values.fetch(autonym))
449
+ end
495
450
  end
496
451
  }
497
452
  end
498
453
 
499
- nil
500
- end
454
+ # @return [nil]
455
+ def _check_requirements
456
+ @requirements.each_pair do |autonym, names|
457
+ names.map! { |name|
458
+ if member?(name)
459
+ autonym_for_name(name)
460
+ else
461
+ raise ArgumentError,
462
+ "`#{autonym}` with invalid requirements `#{names}`"
463
+ end
464
+ }
465
+ end
501
466
 
502
- # @endgroup
467
+ nil
468
+ end
503
469
 
470
+ # @endgroup
471
+ end
504
472
  end
505
-
506
- end; end
473
+ end