xqsr3 0.38.1.1 → 0.39.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -6
  3. data/examples/count_word_frequencies.md +13 -13
  4. data/examples/count_word_frequencies.rb +5 -5
  5. data/lib/xqsr3/array_utilities/join_with_or.rb +53 -54
  6. data/lib/xqsr3/array_utilities.rb +2 -2
  7. data/lib/xqsr3/command_line_utilities/map_option_string.rb +66 -67
  8. data/lib/xqsr3/command_line_utilities.rb +2 -2
  9. data/lib/xqsr3/containers/frequency_map.rb +405 -404
  10. data/lib/xqsr3/containers/multi_map.rb +454 -453
  11. data/lib/xqsr3/containers.rb +3 -3
  12. data/lib/xqsr3/conversion/bool_parser.rb +56 -57
  13. data/lib/xqsr3/conversion/integer_parser.rb +92 -93
  14. data/lib/xqsr3/conversion.rb +3 -3
  15. data/lib/xqsr3/diagnostics/exception_utilities.rb +152 -151
  16. data/lib/xqsr3/diagnostics/exceptions/with_cause.rb +99 -95
  17. data/lib/xqsr3/diagnostics/inspect_builder.rb +86 -86
  18. data/lib/xqsr3/diagnostics.rb +3 -3
  19. data/lib/xqsr3/doc_.rb +136 -136
  20. data/lib/xqsr3/extensions/array/join_with_or.rb +9 -9
  21. data/lib/xqsr3/extensions/enumerable/collect_with_index.rb +18 -17
  22. data/lib/xqsr3/extensions/enumerable/detect_map.rb +41 -41
  23. data/lib/xqsr3/extensions/enumerable/unique.rb +32 -31
  24. data/lib/xqsr3/extensions/hash/deep_transform.rb +1 -1
  25. data/lib/xqsr3/extensions/hash/except.rb +16 -16
  26. data/lib/xqsr3/extensions/hash/has_match.rb +10 -10
  27. data/lib/xqsr3/extensions/hash/match.rb +10 -10
  28. data/lib/xqsr3/extensions/hash/slice.rb +11 -11
  29. data/lib/xqsr3/extensions/hash.rb +1 -1
  30. data/lib/xqsr3/extensions/integer/to_s_grp.rb +118 -0
  31. data/lib/xqsr3/extensions/integer.rb +3 -0
  32. data/lib/xqsr3/extensions/io/writelines.rb +34 -34
  33. data/lib/xqsr3/extensions/kernel/integer.rb +26 -26
  34. data/lib/xqsr3/extensions/kernel/raise_with_options.rb +15 -14
  35. data/lib/xqsr3/extensions/kernel.rb +1 -0
  36. data/lib/xqsr3/extensions/string/ends_with.rb +1 -1
  37. data/lib/xqsr3/extensions/string/map_option_string.rb +4 -5
  38. data/lib/xqsr3/extensions/string/nil_if_empty.rb +1 -1
  39. data/lib/xqsr3/extensions/string/nil_if_whitespace.rb +1 -1
  40. data/lib/xqsr3/extensions/string/quote_if.rb +1 -2
  41. data/lib/xqsr3/extensions/string/starts_with.rb +1 -1
  42. data/lib/xqsr3/extensions/string/to_bool.rb +8 -9
  43. data/lib/xqsr3/extensions/string/to_symbol.rb +1 -1
  44. data/lib/xqsr3/extensions/string/truncate.rb +1 -2
  45. data/lib/xqsr3/extensions/test/unit/assert_eql.rb +7 -7
  46. data/lib/xqsr3/extensions/test/unit/assert_false.rb +6 -7
  47. data/lib/xqsr3/extensions/test/unit/assert_not.rb +6 -7
  48. data/lib/xqsr3/extensions/test/unit/assert_not_eql.rb +7 -7
  49. data/lib/xqsr3/extensions/test/unit/assert_raise_with_message.rb +61 -62
  50. data/lib/xqsr3/extensions/test/unit/assert_subclass_of.rb +7 -8
  51. data/lib/xqsr3/extensions/test/unit/assert_superclass_of.rb +7 -8
  52. data/lib/xqsr3/extensions/test/unit/assert_true.rb +6 -7
  53. data/lib/xqsr3/extensions/test/unit/assert_type_has_instance_methods.rb +36 -38
  54. data/lib/xqsr3/extensions.rb +5 -5
  55. data/lib/xqsr3/hash_utilities/deep_transform.rb +71 -71
  56. data/lib/xqsr3/hash_utilities/key_matching.rb +82 -82
  57. data/lib/xqsr3/hash_utilities.rb +3 -3
  58. data/lib/xqsr3/internal_/test_unit_version_.rb +130 -88
  59. data/lib/xqsr3/io/writelines.rb +125 -125
  60. data/lib/xqsr3/quality/parameter_checking.rb +452 -453
  61. data/lib/xqsr3/quality.rb +2 -2
  62. data/lib/xqsr3/string_utilities/ends_with.rb +64 -64
  63. data/lib/xqsr3/string_utilities/nil_if_empty.rb +33 -34
  64. data/lib/xqsr3/string_utilities/nil_if_whitespace.rb +35 -35
  65. data/lib/xqsr3/string_utilities/quote_if.rb +55 -56
  66. data/lib/xqsr3/string_utilities/starts_with.rb +64 -64
  67. data/lib/xqsr3/string_utilities/to_symbol.rb +80 -80
  68. data/lib/xqsr3/string_utilities/truncate.rb +60 -61
  69. data/lib/xqsr3/string_utilities.rb +8 -8
  70. data/lib/xqsr3/version.rb +19 -20
  71. data/test/performance/frequency_map.rb +13 -27
  72. data/test/scratch/test_assert_raise_with_message.rb +12 -13
  73. data/test/unit/array_utilities/tc_join_with_or.rb +140 -142
  74. data/test/unit/command_line_utilities/tc_map_option_string.rb +18 -18
  75. data/test/unit/containers/tc_frequency_map.rb +607 -554
  76. data/test/unit/containers/tc_multi_map.rb +573 -522
  77. data/test/unit/conversion/tc_integer_parser.rb +73 -73
  78. data/test/unit/conversion/tc_to_bool.rb +26 -26
  79. data/test/unit/diagnostics/exceptions/tc_with_cause.rb +165 -165
  80. data/test/unit/diagnostics/tc_exception_utilities.rb +156 -156
  81. data/test/unit/extensions/enumerable/tc_collect_with_index.rb +14 -14
  82. data/test/unit/extensions/enumerable/tc_detect_map.rb +20 -20
  83. data/test/unit/extensions/enumerable/tc_unique.rb +34 -34
  84. data/test/unit/extensions/hash/tc_deep_transform.rb +22 -22
  85. data/test/unit/extensions/hash/tc_except.rb +28 -28
  86. data/test/unit/extensions/hash/tc_hash.rb +1 -1
  87. data/test/unit/extensions/hash/tc_slice.rb +14 -14
  88. data/test/unit/extensions/integer/tc_to_s_grp.rb +60 -0
  89. data/test/unit/extensions/integer/ts_all.rb +12 -0
  90. data/test/unit/extensions/io/tc_writelines.rb +77 -77
  91. data/test/unit/extensions/kernel/tc_integer.rb +75 -75
  92. data/test/unit/extensions/kernel/tc_raise_with_options.rb +155 -155
  93. data/test/unit/extensions/object/tc_inspect.rb +51 -51
  94. data/test/unit/extensions/string/tc_bool.tb +24 -24
  95. data/test/unit/extensions/string/tc_ends_with.rb +53 -53
  96. data/test/unit/extensions/string/tc_map_option_string.rb +15 -15
  97. data/test/unit/extensions/string/tc_nil_if_empty.rb +8 -8
  98. data/test/unit/extensions/string/tc_nil_if_whitespace.rb +8 -8
  99. data/test/unit/extensions/string/tc_quote_if.rb +18 -18
  100. data/test/unit/extensions/string/tc_starts_with.rb +53 -53
  101. data/test/unit/extensions/string/tc_to_symbol.rb +26 -26
  102. data/test/unit/extensions/string/tc_truncate.rb +18 -18
  103. data/test/unit/extensions/test/unit/tc_assert_raise_with_message.rb +16 -16
  104. data/test/unit/extensions/test/unit/tc_assert_subclass_of.rb +9 -9
  105. data/test/unit/extensions/test/unit/tc_assert_superclass_of.rb +9 -9
  106. data/test/unit/hash_utilities/tc_has_match.rb +70 -70
  107. data/test/unit/hash_utilities/tc_match.rb +83 -83
  108. data/test/unit/io/tc_writelines.rb +106 -108
  109. data/test/unit/quality/tc_parameter_checking.rb +390 -390
  110. data/test/unit/string_utilities/tc_truncate.rb +28 -28
  111. data/test/unit/tc_version.rb +15 -15
  112. metadata +6 -2
@@ -1,17 +1,17 @@
1
1
 
2
2
  # ######################################################################## #
3
- # File: lib/xqsr3/quality/parameter_checking.rb
3
+ # File: lib/xqsr3/quality/parameter_checking.rb
4
4
  #
5
- # Purpose: Definition of the ParameterChecking module
5
+ # Purpose: Definition of the ParameterChecking module
6
6
  #
7
- # Created: 12th February 2015
8
- # Updated: 4th November 2023
7
+ # Created: 12th February 2015
8
+ # Updated: 29th March 2024
9
9
  #
10
- # Home: http://github.com/synesissoftware/xqsr3
10
+ # Home: http://github.com/synesissoftware/xqsr3
11
11
  #
12
- # Author: Matthew Wilson
12
+ # Author: Matthew Wilson
13
13
  #
14
- # Copyright (c) 2019-2023, Matthew Wilson and Synesis Information Systems
14
+ # Copyright (c) 2019-2024, Matthew Wilson and Synesis Information Systems
15
15
  # Copyright (c) 2016-2019, Matthew Wilson and Synesis Software
16
16
  # All rights reserved.
17
17
  #
@@ -26,7 +26,7 @@
26
26
  # notice, this list of conditions and the following disclaimer in the
27
27
  # documentation and/or other materials provided with the distribution.
28
28
  #
29
- # * Neither the names of the copyright holder nor the names of its
29
+ # * Neither the names of the copyright holders nor the names of its
30
30
  # contributors may be used to endorse or promote products derived from
31
31
  # this software without specific prior written permission.
32
32
  #
@@ -60,627 +60,627 @@ module Quality
60
60
  #
61
61
  module ParameterChecking
62
62
 
63
- private
64
- # @!visibility private
65
- module Util_ # :nodoc: all
66
-
67
- def self.join_with_or a
68
-
69
- case a.size
70
- when 1
71
-
72
- a[0]
73
- when 2
74
-
75
- "#{a[0]} or #{a[1]}"
76
- else
77
-
78
- "#{a[0...-1].join(', ')}, or #{a[-1]}"
79
- end
80
- end
81
-
82
- module Constants # :nodoc:
83
-
84
- RECOGNISED_OPTION_NAMES = %w{
85
-
86
- allow_nil
87
- ignore_case
88
- message
89
- nil
90
- nothrow
91
- reject_empty
92
- require_empty
93
- responds_to
94
- strip_str_whitespace
95
- treat_as_option
96
- type
97
- types
98
- values
99
- }.map { |v| v.to_sym }
100
-
101
- end # module Constants
102
- end # module Util_
103
- public
104
-
105
- def self.included base # :nodoc:
106
-
107
- base.extend self
108
- end
109
-
110
- private
111
- # Check a given parameter (value=+value+, name=+name+) for type and value
112
- #
113
- # === Signature
114
- #
115
- # * *Parameters:*
116
- # - +value+ the parameter whose value and type is to be checked
117
- # - +name+ (::String, ::Symbol) the name of the parameter to be checked
118
- # - +options+ (::Hash) options that moderate the behaviour
119
- #
120
- # * *Options:*
121
- # - +:allow_nil+ (boolean) The +value+ must not be +nil+ unless this option is true
122
- # - +:nil+ an alias for +:allow_nil+
123
- # - +:ignore_case+ (boolean) When +:values+ is specified, comparisons of strings, or arrays of strings, will be carried out in a case-insensitive manner
124
- # - +:types+ (::Array) An array of types one of which +value+ must be (or must be derived from). One of these types may be an array of types, in which case +value+ may be an array that must consist wholly of those types
125
- # - +:type+ (::Class) A single type parameter, used only if +:types+ is not specified
126
- # - +:values+ (::Array) an array of values one of which +value+ must be
127
- # - +:responds_to+ (::Array) An array of symbols specifying all messages to which the parameter will respond
128
- # - +:reject_empty+ (boolean) requires value to respond to +empty?+ message and to do so with false, unless +nil+
129
- # - +:require_empty+ (boolean) requires value to respond to +empty?+ message and to do so with true, unless +nil+
130
- # - +:nothrow+ (boolean) causes failure to be indicated by a +nil+ return rather than a thrown exception
131
- # - +:message+ (::String) specifies a message to be used in any thrown exception, which suppresses internal message preparation
132
- # - +:strip_str_whitespace+ (boolean) If +value+ is a string (as determined by responding to +to_str+ message), then it will be stripped - leading and trailing whitespace removed - before any processing
133
- # - +:treat_as_option+ (boolean) If true, the value will be treated as an option when reporting check failure
134
- #
135
- # This method is private, because it should only be used within methods
136
- def check_parameter value, name, options = {}, &block
137
-
138
- Util_.check_parameter value, name, options, &block
139
- end
140
-
141
- # @see check_parameter
142
- #
143
- # @note This is obsolete, and will be removed in a future version.
144
- # Please use +check_parameter+ instead
145
- def check_param value, name, options = {}, &block
146
-
147
- Util_.check_parameter value, name, options, &block
148
- end
149
-
150
- # Specific form of the +check_parameter()+ that is used to check
151
- # options, taking instead the hash and the key
152
- #
153
- # === Signature
154
- #
155
- # * *Parameters:*
156
- # - +h+ (::Hash) The options hash from which the named element is to be tested. May not be +nil+
157
- # - +name+ (::String, ::Symbol, [ ::String, ::Symbol ]) The options key name, or an array of names. May not be +nil+
158
- # - +options+ (::Hash) options that moderate the behaviour in the same way as for +check_parameter()+ except that the +:treat_as_option+ option (with the value +true+) is merged in before calling +check_parameter()+
159
- #
160
- # * *Options:*
161
- def check_option h, name, options = {}, &block
162
-
163
- Util_.check_option h, name, options, &block
164
- end
165
-
166
- public
167
- # Check a given parameter (value=+value+, name=+name+) for type and value
168
- #
169
- # === Signature
170
- #
171
- # * *Parameters:*
172
- # - +value+ the parameter whose value and type is to be checked
173
- # - +name+ the name of the parameter to be checked
174
- # - +options+ options
175
- #
176
- # * *Options:*
177
- # - +:allow_nil+ (boolean) The +value+ must not be +nil+ unless this option is true
178
- # - +:nil+ an alias for +:allow_nil+
179
- # - +:ignore_case+ (boolean) When +:values+ is specified, comparisons of strings, or arrays of strings, will be carried out in a case-insensitive manner
180
- # - +:types+ (::Array) An array of types one of which +value+ must be (or must be derived from). One of these types may be an array of types, in which case +value+ may be an array that must consist wholly of those types
181
- # - +:type+ (::Class) A single type parameter, used only if +:types+ is not specified
182
- # - +:values+ (::Array) an array of values one of which +value+ must be
183
- # - +:responds_to+ (::Array) An array of symbols specifying all messages to which the parameter will respond
184
- # - +:reject_empty+ (boolean) requires value to respond to +empty?+ message and to do so with false, unless +nil+
185
- # - +:require_empty+ (boolean) requires value to respond to +empty?+ message and to do so with true, unless +nil+
186
- # - +:nothrow+ (boolean) causes failure to be indicated by a +nil+ return rather than a thrown exception
187
- # - +:message+ (boolean) specifies a message to be used in any thrown exception, which suppresses internal message preparation
188
- # - +:treat_as_option+ (boolean) If true, the value will be treated as an option when reporting check failure
189
- #
190
- def self.check_parameter value, name, options = {}, &block
191
-
192
- Util_.check_parameter value, name, options, &block
193
- end
194
-
195
- # @see check_parameter
196
- #
197
- # @note This is obsolete, and will be removed in a future version.
198
- # Please use +check_parameter+ instead
199
- def self.check_param value, name, options = {}, &block
200
-
201
- Util_.check_parameter value, name, options, &block
202
- end
203
-
204
- # Specific form of the +check_parameter()+ that is used to check
205
- # options, taking instead the hash and the key
206
- #
207
- # === Signature
208
- #
209
- # * *Parameters:*
210
- # - +h+ (::Hash) The options hash from which the named element is to be tested. May not be +nil+
211
- # - +name+ (::String, ::Symbol, [ ::String, ::Symbol ]) The options key name, or an array of names. May not be +nil+
212
- # - +options+ (::Hash) options that moderate the behaviour in the same way as for +check_parameter()+ except that the +:treat_as_option+ option (with the value +true+) is merged in before calling +check_parameter()+
213
- #
214
- # * *Options:*
215
- def self.check_option h, name, options = {}, &block
63
+ private
64
+ # @!visibility private
65
+ module Util_ # :nodoc: all
66
+
67
+ def self.join_with_or a
68
+
69
+ case a.size
70
+ when 1
71
+
72
+ a[0]
73
+ when 2
74
+
75
+ "#{a[0]} or #{a[1]}"
76
+ else
77
+
78
+ "#{a[0...-1].join(', ')}, or #{a[-1]}"
79
+ end
80
+ end
81
+
82
+ module Constants # :nodoc:
83
+
84
+ RECOGNISED_OPTION_NAMES = %w{
85
+
86
+ allow_nil
87
+ ignore_case
88
+ message
89
+ nil
90
+ nothrow
91
+ reject_empty
92
+ require_empty
93
+ responds_to
94
+ strip_str_whitespace
95
+ treat_as_option
96
+ type
97
+ types
98
+ values
99
+ }.map { |v| v.to_sym }
100
+
101
+ end # module Constants
102
+ end # module Util_
103
+ public
104
+
105
+ def self.included base # :nodoc:
106
+
107
+ base.extend self
108
+ end
109
+
110
+ private
111
+ # Check a given parameter (value=+value+, name=+name+) for type and value
112
+ #
113
+ # === Signature
114
+ #
115
+ # * *Parameters:*
116
+ # - +value+ the parameter whose value and type is to be checked
117
+ # - +name+ (::String, ::Symbol) the name of the parameter to be checked
118
+ # - +options+ (::Hash) options that moderate the behaviour
119
+ #
120
+ # * *Options:*
121
+ # - +:allow_nil+ (boolean) The +value+ must not be +nil+ unless this option is true
122
+ # - +:nil+ an alias for +:allow_nil+
123
+ # - +:ignore_case+ (boolean) When +:values+ is specified, comparisons of strings, or arrays of strings, will be carried out in a case-insensitive manner
124
+ # - +:types+ (::Array) An array of types one of which +value+ must be (or must be derived from). One of these types may be an array of types, in which case +value+ may be an array that must consist wholly of those types
125
+ # - +:type+ (::Class) A single type parameter, used only if +:types+ is not specified
126
+ # - +:values+ (::Array) an array of values one of which +value+ must be
127
+ # - +:responds_to+ (::Array) An array of symbols specifying all messages to which the parameter will respond
128
+ # - +:reject_empty+ (boolean) requires value to respond to +empty?+ message and to do so with false, unless +nil+
129
+ # - +:require_empty+ (boolean) requires value to respond to +empty?+ message and to do so with true, unless +nil+
130
+ # - +:nothrow+ (boolean) causes failure to be indicated by a +nil+ return rather than a thrown exception
131
+ # - +:message+ (::String) specifies a message to be used in any thrown exception, which suppresses internal message preparation
132
+ # - +:strip_str_whitespace+ (boolean) If +value+ is a string (as determined by responding to +to_str+ message), then it will be stripped - leading and trailing whitespace removed - before any processing
133
+ # - +:treat_as_option+ (boolean) If true, the value will be treated as an option when reporting check failure
134
+ #
135
+ # This method is private, because it should only be used within methods
136
+ def check_parameter value, name, options = {}, &block
137
+
138
+ Util_.check_parameter value, name, options, &block
139
+ end
140
+
141
+ # @see check_parameter
142
+ #
143
+ # @note This is obsolete, and will be removed in a future version.
144
+ # Please use +check_parameter+ instead
145
+ def check_param value, name, options = {}, &block
146
+
147
+ Util_.check_parameter value, name, options, &block
148
+ end
149
+
150
+ # Specific form of the +check_parameter()+ that is used to check
151
+ # options, taking instead the hash and the key
152
+ #
153
+ # === Signature
154
+ #
155
+ # * *Parameters:*
156
+ # - +h+ (::Hash) The options hash from which the named element is to be tested. May not be +nil+
157
+ # - +name+ (::String, ::Symbol, [ ::String, ::Symbol ]) The options key name, or an array of names. May not be +nil+
158
+ # - +options+ (::Hash) options that moderate the behaviour in the same way as for +check_parameter()+ except that the +:treat_as_option+ option (with the value +true+) is merged in before calling +check_parameter()+
159
+ #
160
+ # * *Options:*
161
+ def check_option h, name, options = {}, &block
162
+
163
+ Util_.check_option h, name, options, &block
164
+ end
165
+
166
+ public
167
+ # Check a given parameter (value=+value+, name=+name+) for type and value
168
+ #
169
+ # === Signature
170
+ #
171
+ # * *Parameters:*
172
+ # - +value+ the parameter whose value and type is to be checked
173
+ # - +name+ the name of the parameter to be checked
174
+ # - +options+ options
175
+ #
176
+ # * *Options:*
177
+ # - +:allow_nil+ (boolean) The +value+ must not be +nil+ unless this option is true
178
+ # - +:nil+ an alias for +:allow_nil+
179
+ # - +:ignore_case+ (boolean) When +:values+ is specified, comparisons of strings, or arrays of strings, will be carried out in a case-insensitive manner
180
+ # - +:types+ (::Array) An array of types one of which +value+ must be (or must be derived from). One of these types may be an array of types, in which case +value+ may be an array that must consist wholly of those types
181
+ # - +:type+ (::Class) A single type parameter, used only if +:types+ is not specified
182
+ # - +:values+ (::Array) an array of values one of which +value+ must be
183
+ # - +:responds_to+ (::Array) An array of symbols specifying all messages to which the parameter will respond
184
+ # - +:reject_empty+ (boolean) requires value to respond to +empty?+ message and to do so with false, unless +nil+
185
+ # - +:require_empty+ (boolean) requires value to respond to +empty?+ message and to do so with true, unless +nil+
186
+ # - +:nothrow+ (boolean) causes failure to be indicated by a +nil+ return rather than a thrown exception
187
+ # - +:message+ (boolean) specifies a message to be used in any thrown exception, which suppresses internal message preparation
188
+ # - +:treat_as_option+ (boolean) If true, the value will be treated as an option when reporting check failure
189
+ #
190
+ def self.check_parameter value, name, options = {}, &block
191
+
192
+ Util_.check_parameter value, name, options, &block
193
+ end
194
+
195
+ # @see check_parameter
196
+ #
197
+ # @note This is obsolete, and will be removed in a future version.
198
+ # Please use +check_parameter+ instead
199
+ def self.check_param value, name, options = {}, &block
200
+
201
+ Util_.check_parameter value, name, options, &block
202
+ end
203
+
204
+ # Specific form of the +check_parameter()+ that is used to check
205
+ # options, taking instead the hash and the key
206
+ #
207
+ # === Signature
208
+ #
209
+ # * *Parameters:*
210
+ # - +h+ (::Hash) The options hash from which the named element is to be tested. May not be +nil+
211
+ # - +name+ (::String, ::Symbol, [ ::String, ::Symbol ]) The options key name, or an array of names. May not be +nil+
212
+ # - +options+ (::Hash) options that moderate the behaviour in the same way as for +check_parameter()+ except that the +:treat_as_option+ option (with the value +true+) is merged in before calling +check_parameter()+
213
+ #
214
+ # * *Options:*
215
+ def self.check_option h, name, options = {}, &block
216
216
 
217
- Util_.check_option h, name, options, &block
218
- end
217
+ Util_.check_option h, name, options, &block
218
+ end
219
219
 
220
- private
221
- def Util_.check_option h, names, options = {}, &block
220
+ private
221
+ def Util_.check_option h, names, options = {}, &block
222
222
 
223
- warn "#{self}::#{__method__}: given parameter h - value '#{h.inspect}' - must be a #{::Hash} but is a #{h.class}" unless ::Hash === h
223
+ warn "#{self}::#{__method__}: given parameter h - value '#{h.inspect}' - must be a #{::Hash} but is a #{h.class}" unless ::Hash === h
224
224
 
225
- case names
226
- when ::Array
225
+ case names
226
+ when ::Array
227
227
 
228
- allow_nil = options[:allow_nil] || options[:nil]
228
+ allow_nil = options[:allow_nil] || options[:nil]
229
229
 
230
- # find the first item whose name is in the hash ...
230
+ # find the first item whose name is in the hash ...
231
231
 
232
- found_name = names.find { |name| h.has_key?(name) }
232
+ found_name = names.find { |name| h.has_key?(name) }
233
233
 
234
- if found_name.nil? && allow_nil
234
+ if found_name.nil? && allow_nil
235
235
 
236
- return nil
237
- end
236
+ return nil
237
+ end
238
238
 
239
- # ... or use the first (just to get a name for reporting)
239
+ # ... or use the first (just to get a name for reporting)
240
240
 
241
- found_name ||= names[0]
241
+ found_name ||= names[0]
242
242
 
243
- Util_.check_parameter h[found_name], found_name, options.merge({ treat_as_option: true }), &block
244
- else
243
+ Util_.check_parameter h[found_name], found_name, options.merge({ treat_as_option: true }), &block
244
+ else
245
245
 
246
- name = names
246
+ name = names
247
247
 
248
- Util_.check_parameter h[name], name, options.merge({ treat_as_option: true }), &block
249
- end
250
- end
248
+ Util_.check_parameter h[name], name, options.merge({ treat_as_option: true }), &block
249
+ end
250
+ end
251
251
 
252
- def Util_.check_parameter value, name, options, &block
252
+ def Util_.check_parameter value, name, options, &block
253
253
 
254
- if $DEBUG
254
+ if $DEBUG
255
255
 
256
- unrecognised_option_names = options.keys - Util_::Constants::RECOGNISED_OPTION_NAMES
256
+ unrecognised_option_names = options.keys - Util_::Constants::RECOGNISED_OPTION_NAMES
257
257
 
258
- unless unrecognised_option_names.empty?
258
+ unless unrecognised_option_names.empty?
259
259
 
260
- s = "#{self}::check_parameter: the following options are not recognised:"
260
+ s = "#{self}::check_parameter: the following options are not recognised:"
261
261
 
262
- unrecognised_option_names.each { |n| s += "\n\t'#{n}'" }
262
+ unrecognised_option_names.each { |n| s += "\n\t'#{n}'" }
263
263
 
264
- warn s
265
- end
266
- end
264
+ warn s
265
+ end
266
+ end
267
267
 
268
- # strip whitespace
268
+ # strip whitespace
269
269
 
270
- if !value.nil? && options[:strip_str_whitespace]
270
+ if !value.nil? && options[:strip_str_whitespace]
271
271
 
272
- if value.respond_to? :to_str
272
+ if value.respond_to? :to_str
273
273
 
274
- value = value.to_str.strip
275
- else
274
+ value = value.to_str.strip
275
+ else
276
276
 
277
- warn "#{self}::#{__method__}: options[:strip_str_whitespace] specified but value - '#{value}' (#{value.class}) - does not respond to to_str" unless value.respond_to? :to_str
278
- end
279
- end
277
+ warn "#{self}::#{__method__}: options[:strip_str_whitespace] specified but value - '#{value}' (#{value.class}) - does not respond to to_str" unless value.respond_to? :to_str
278
+ end
279
+ end
280
280
 
281
281
 
282
- failed_check = false
283
- options ||= {}
284
- message = options[:message]
285
- treat_as_option = options[:treat_as_option]
286
- return_value = value
287
- param_s = treat_as_option ? 'option' : 'parameter'
288
- allow_nil = options[:allow_nil] || options[:nil]
282
+ failed_check = false
283
+ options ||= {}
284
+ message = options[:message]
285
+ treat_as_option = options[:treat_as_option]
286
+ param_s = treat_as_option ? 'option' : 'parameter'
287
+ allow_nil = options[:allow_nil] || options[:nil]
289
288
 
290
- warn "#{self}::check_parameter: invoked with non-string/non-symbol name: name.class=#{name.class}" unless name && [ ::String, ::Symbol ].any? { |c| name.is_a?(c) }
289
+ warn "#{self}::check_parameter: invoked with non-string/non-symbol name: name.class=#{name.class}" unless name && [ ::String, ::Symbol ].any? { |c| name.is_a?(c) }
291
290
 
292
- if treat_as_option
291
+ if treat_as_option
293
292
 
294
- case name
295
- when ::String
293
+ case name
294
+ when ::String
296
295
 
297
- ;
298
- when ::Symbol
296
+ ;
297
+ when ::Symbol
299
298
 
300
- name = ':' + name.to_s
301
- else
302
- end
303
- end
299
+ name = ':' + name.to_s
300
+ else
301
+ end
302
+ end
304
303
 
305
304
 
306
- # nil check
305
+ # nil check
307
306
 
308
- if value.nil? && !allow_nil
307
+ if value.nil? && !allow_nil
309
308
 
310
- failed_check = true
309
+ failed_check = true
311
310
 
312
- unless options[:nothrow]
311
+ unless options[:nothrow]
313
312
 
314
- unless message
313
+ unless message
315
314
 
316
- if name.nil?
315
+ if name.nil?
317
316
 
318
- message = "#{param_s} may not be nil"
319
- else
317
+ message = "#{param_s} may not be nil"
318
+ else
320
319
 
321
- message = "#{param_s} '#{name}' may not be nil"
322
- end
323
- end
320
+ message = "#{param_s} '#{name}' may not be nil"
321
+ end
322
+ end
324
323
 
325
- raise ArgumentError, message
326
- end
327
- end
324
+ raise ArgumentError, message
325
+ end
326
+ end
328
327
 
329
- # check type(s)
328
+ # check type(s)
330
329
 
331
- unless value.nil?
330
+ unless value.nil?
332
331
 
333
- # types
332
+ # types
334
333
 
335
- types = options[:types] || []
336
- if options.has_key? :type
334
+ types = options[:types] || []
335
+ if options.has_key? :type
337
336
 
338
- types << options[:type] if types.empty?
339
- end
340
- types = [value.class] if types.empty?
341
- types = types.map { |type| :boolean == type ? [ ::TrueClass, ::FalseClass ] : type }.flatten if types.include?(:boolean)
337
+ types << options[:type] if types.empty?
338
+ end
339
+ types = [value.class] if types.empty?
340
+ types = types.map { |type| :boolean == type ? [ ::TrueClass, ::FalseClass ] : type }.flatten if types.include?(:boolean)
342
341
 
343
- warn "#{self}::check_parameter: options[:types] of type #{types.class} - should be #{::Array}" unless types.is_a?(Array)
344
- warn "#{self}::check_parameter: options[:types] - '#{types}' - should contain only classes or arrays of classes" if types.is_a?(::Array) && !types.all? { |c| ::Class === c || (::Array === c && c.all? { |c2| ::Class === c2 }) }
342
+ warn "#{self}::check_parameter: options[:types] of type #{types.class} - should be #{::Array}" unless types.is_a?(Array)
343
+ warn "#{self}::check_parameter: options[:types] - '#{types}' - should contain only classes or arrays of classes" if types.is_a?(::Array) && !types.all? { |c| ::Class === c || (::Array === c && c.all? { |c2| ::Class === c2 }) }
345
344
 
346
- unless types.any? do |t|
345
+ unless types.any? do |t|
347
346
 
348
- case t
349
- when ::Class
347
+ case t
348
+ when ::Class
350
349
 
351
- # the (presumed) scalar argument is of type t?
352
- value.is_a?(t)
353
- when ::Array
350
+ # the (presumed) scalar argument is of type t?
351
+ value.is_a?(t)
352
+ when ::Array
354
353
 
355
- # the (presumed) vector argument's elements are the
356
- # possible types
357
- value.all? { |v| t.any? { |t2| v.is_a?(t2) }} if ::Array === value
358
- else
354
+ # the (presumed) vector argument's elements are the
355
+ # possible types
356
+ value.all? { |v| t.any? { |t2| v.is_a?(t2) }} if ::Array === value
357
+ else
359
358
 
360
- end
361
- end then
359
+ end
360
+ end then
362
361
 
363
- failed_check = true
362
+ failed_check = true
364
363
 
365
- unless options[:nothrow]
364
+ unless options[:nothrow]
366
365
 
367
- unless message
366
+ unless message
368
367
 
369
- s_name = name.is_a?(String) ? "'#{name}' " : ''
368
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
370
369
 
371
- types_0 = types.select { |t| ::Class === t }.uniq
372
- types_ar = types.select { |t| ::Array === t }.flatten.uniq
370
+ types_0 = types.select { |t| ::Class === t }.uniq
371
+ types_ar = types.select { |t| ::Array === t }.flatten.uniq
373
372
 
374
- if types_ar.empty?
373
+ if types_ar.empty?
375
374
 
376
- s_types_0 = Util_.join_with_or types_0
375
+ s_types_0 = Util_.join_with_or types_0
377
376
 
378
- message = "#{param_s} #{s_name}(#{value.class}) must be an instance of #{s_types_0}"
379
- elsif types_0.empty?
377
+ message = "#{param_s} #{s_name}(#{value.class}) must be an instance of #{s_types_0}"
378
+ elsif types_0.empty?
380
379
 
381
- s_types_ar = Util_.join_with_or types_ar
380
+ s_types_ar = Util_.join_with_or types_ar
382
381
 
383
- message = "#{param_s} #{s_name}(#{value.class}) must be an array containing instance(s) of #{s_types_ar}"
384
- else
382
+ message = "#{param_s} #{s_name}(#{value.class}) must be an array containing instance(s) of #{s_types_ar}"
383
+ else
385
384
 
386
- s_types_0 = Util_.join_with_or types_0
385
+ s_types_0 = Util_.join_with_or types_0
387
386
 
388
- s_types_ar = Util_.join_with_or types_ar
387
+ s_types_ar = Util_.join_with_or types_ar
389
388
 
390
- message = "#{param_s} #{s_name}(#{value.class}) must be an instance of #{s_types_0}, or an array containing instance(s) of #{s_types_ar}"
391
- end
392
- end
389
+ message = "#{param_s} #{s_name}(#{value.class}) must be an instance of #{s_types_0}, or an array containing instance(s) of #{s_types_ar}"
390
+ end
391
+ end
393
392
 
394
- raise TypeError, message
395
- end
396
- end
393
+ raise TypeError, message
394
+ end
395
+ end
397
396
 
398
397
 
399
- # messages
398
+ # messages
400
399
 
401
- messages = options[:responds_to] || []
402
- messages = [ messages ] unless messages.respond_to? :each
400
+ messages = options[:responds_to] || []
401
+ messages = [ messages ] unless messages.respond_to? :each
403
402
 
404
- warn "#{self}::check_parameter: options[:responds_to] of type #{messages.class} - should be #{::Array}" unless messages.is_a?(Array)
405
- warn "#{self}::check_parameter: options[:responds_to] should contain only symbols or strings" if messages.is_a?(::Array) && !messages.all? { |m| ::Symbol === m || ::String === m }
403
+ warn "#{self}::check_parameter: options[:responds_to] of type #{messages.class} - should be #{::Array}" unless messages.is_a?(Array)
404
+ warn "#{self}::check_parameter: options[:responds_to] should contain only symbols or strings" if messages.is_a?(::Array) && !messages.all? { |m| ::Symbol === m || ::String === m }
406
405
 
407
- messages.each do |m|
406
+ messages.each do |m|
408
407
 
409
- unless value.respond_to? m
408
+ unless value.respond_to? m
410
409
 
411
- s_name = name.is_a?(String) ? "'#{name}' " : ''
410
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
412
411
 
413
- raise TypeError, "#{param_s} #{s_name}(#{value.class}) must respond to the '#{m}' message"
414
- end
415
- end
412
+ raise TypeError, "#{param_s} #{s_name}(#{value.class}) must respond to the '#{m}' message"
413
+ end
414
+ end
416
415
 
417
- end
416
+ end
418
417
 
419
- # reject/require empty?
418
+ # reject/require empty?
420
419
 
421
- unless value.nil?
420
+ unless value.nil?
422
421
 
423
- if options[:reject_empty]
422
+ if options[:reject_empty]
424
423
 
425
- warn "#{self}::check_parameter: value '#{value}' of type #{value.class} does not respond to empty?" unless value.respond_to? :empty?
424
+ warn "#{self}::check_parameter: value '#{value}' of type #{value.class} does not respond to empty?" unless value.respond_to? :empty?
426
425
 
427
- if value.empty?
426
+ if value.empty?
428
427
 
429
- failed_check = true
428
+ failed_check = true
430
429
 
431
- unless options[:nothrow]
430
+ unless options[:nothrow]
432
431
 
433
- unless message
434
- s_name = name.is_a?(String) ? "'#{name}' " : ''
432
+ unless message
433
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
435
434
 
436
- message = "#{param_s} #{s_name}must not be empty"
437
- end
435
+ message = "#{param_s} #{s_name}must not be empty"
436
+ end
438
437
 
439
- raise ArgumentError, message
440
- end
441
- end
442
- end
438
+ raise ArgumentError, message
439
+ end
440
+ end
441
+ end
443
442
 
444
- if options[:require_empty]
443
+ if options[:require_empty]
445
444
 
446
- warn "#{self}::check_parameter: value '#{value}' of type #{value.class} does not respond to empty?" unless value.respond_to? :empty?
445
+ warn "#{self}::check_parameter: value '#{value}' of type #{value.class} does not respond to empty?" unless value.respond_to? :empty?
447
446
 
448
- unless value.empty?
447
+ unless value.empty?
449
448
 
450
- failed_check = true
449
+ failed_check = true
451
450
 
452
- unless options[:nothrow]
451
+ unless options[:nothrow]
453
452
 
454
- unless message
453
+ unless message
455
454
 
456
- s_name = name.is_a?(String) ? "'#{name}' " : ''
455
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
457
456
 
458
- message = "#{param_s} #{s_name}must be empty"
459
- end
457
+ message = "#{param_s} #{s_name}must be empty"
458
+ end
460
459
 
461
- raise ArgumentError, message
462
- end
463
- end
464
- end
465
- end
460
+ raise ArgumentError, message
461
+ end
462
+ end
463
+ end
464
+ end
466
465
 
467
- # check value(s)
466
+ # run block
468
467
 
469
- unless value.nil? || !(values = options[:values])
468
+ if value and block
470
469
 
471
- warn "#{self}::check_parameter: options[:values] of type #{values.class} - should be #{::Array}" unless values.is_a?(Array)
470
+ warn "#{self}::check_parameter: block arity must be 1 or 2" unless (1..2).include? block.arity
472
471
 
473
- found = false
472
+ r = nil
474
473
 
475
- io = options[:ignore_order] && ::Array === value
474
+ begin
476
475
 
477
- do_case = options[:ignore_case] ? lambda do |v|
476
+ if 1 == block.arity
478
477
 
479
- case v
480
- when ::String
478
+ r = block.call(value)
479
+ else
481
480
 
482
- return :string
483
- when ::Array
481
+ r = block.call(value, options)
482
+ end
484
483
 
485
- return :array_of_strings if v.all? { |s| ::String === s }
486
- end
484
+ rescue StandardError => x
487
485
 
488
- nil
489
- end : lambda { |v| nil }
486
+ xmsg = x.message || ''
490
487
 
491
- value_ic = do_case.call(value)
492
- value_io = nil
493
- value_uc = nil
488
+ if xmsg.empty?
494
489
 
495
- values.each do |v|
490
+ xmsg ||= message
496
491
 
497
- if ::Range === v && !(::Range === value) && v.cover?(value)
492
+ if xmsg.empty?
498
493
 
499
- found = true
500
- break
501
- end
494
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
495
+ xmsg = "#{param_s} #{s_name}failed validation against caller-supplied block"
496
+ end
502
497
 
503
- if value == v
498
+ raise $!, xmsg, $!.backtrace
499
+ end
504
500
 
505
- found = true
506
- break
507
- end
501
+ raise
502
+ end
508
503
 
509
- # ignore-case comparing
504
+ if r.is_a?(::Exception)
510
505
 
511
- if value_ic
506
+ # An exception returned from the block, so raise it, with
507
+ # its message or a custom message
512
508
 
513
- unless value_uc
509
+ x = r
510
+ xmsg = x.message || ''
514
511
 
515
- case value_ic
516
- when :string
512
+ if xmsg.empty?
517
513
 
518
- value_uc = value.upcase
519
- when :array_of_strings
514
+ xmsg ||= message
520
515
 
521
- value_uc = value.map { |s| s.upcase }
522
- value_uc = value_uc.sort if io
523
- end
524
- end
516
+ if xmsg.empty?
525
517
 
526
- v_ic = do_case.call(v)
518
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
519
+ xmsg = "#{param_s} #{s_name}failed validation against caller-supplied block"
520
+ end
527
521
 
528
- if v_ic == value_ic
522
+ raise x, xmsg
523
+ end
529
524
 
530
- case v_ic
531
- when :string
525
+ raise x
532
526
 
533
- if value_uc == v.upcase
527
+ elsif !r
534
528
 
535
- found = true
536
- break
537
- end
538
- when :array_of_strings
529
+ failed_check = true
539
530
 
540
- v_uc = v.map { |s| s.upcase }
541
- v_uc = v_uc.sort if io
531
+ unless options[:nothrow]
542
532
 
543
- if value_uc == v_uc
533
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
534
+ xmsg = "#{param_s} #{s_name}failed validation against caller-supplied block"
544
535
 
545
- found = true
546
- break
547
- end
548
- end
549
- end
550
- elsif io
536
+ if value.is_a?(::Numeric)
551
537
 
552
- unless value_io
538
+ raise RangeError, xmsg
539
+ else
553
540
 
554
- value_io = value.sort
555
- end
541
+ raise ArgumentError, xmsg
542
+ end
543
+ end
556
544
 
557
- if ::Array === v
545
+ elsif r.is_a?(::TrueClass)
558
546
 
559
- v_io = v.sort
547
+ ;
548
+ else
560
549
 
561
- if value_io == v_io
550
+ value = r
551
+ end
552
+ end
562
553
 
563
- found = true
564
- break
565
- end
566
- end
567
- end
568
- end
554
+ # check value(s)
569
555
 
570
- unless found
556
+ unless value.nil? || !(values = options[:values])
571
557
 
572
- failed_check = true
558
+ warn "#{self}::check_parameter: options[:values] of type #{values.class} - should be #{::Array}" unless values.is_a?(Array)
573
559
 
574
- unless options[:nothrow]
560
+ found = false
575
561
 
576
- unless message
562
+ io = options[:ignore_order] && ::Array === value
577
563
 
578
- s_name = name.is_a?(String) ? "'#{name}' " : ''
564
+ do_case = options[:ignore_case] ? lambda do |v|
579
565
 
580
- message = "#{param_s} #{s_name}value '#{value}' not found equal/within any of required values or ranges"
581
- end
566
+ case v
567
+ when ::String
582
568
 
583
- if value.is_a?(::Numeric)
569
+ :string
570
+ when ::Array
584
571
 
585
- raise RangeError, message
586
- else
572
+ :array_of_strings if v.all? { |s| ::String === s }
573
+ else
587
574
 
588
- raise ArgumentError, message
589
- end
590
- end
591
- end
592
- end
575
+ nil
576
+ end
577
+ end : lambda { |v| nil }
593
578
 
594
- # run block
579
+ value_ic = do_case.call(value)
580
+ value_io = nil
581
+ value_uc = nil
595
582
 
596
- if value and block
583
+ values.each do |v|
597
584
 
598
- warn "#{self}::check_parameter: block arity must be 1 or 2" unless (1..2).include? block.arity
585
+ if ::Range === v && !(::Range === value) && v.cover?(value)
599
586
 
600
- r = nil
587
+ found = true
588
+ break
589
+ end
601
590
 
602
- begin
591
+ if value == v
603
592
 
604
- if 1 == block.arity
593
+ found = true
594
+ break
595
+ end
605
596
 
606
- r = block.call(value)
607
- else
597
+ # ignore-case comparing
608
598
 
609
- r = block.call(value, options)
610
- end
599
+ if value_ic
611
600
 
612
- rescue StandardError => x
601
+ unless value_uc
613
602
 
614
- xmsg = x.message || ''
603
+ case value_ic
604
+ when :string
615
605
 
616
- if xmsg.empty?
606
+ value_uc = value.upcase
607
+ when :array_of_strings
617
608
 
618
- xmsg ||= message
609
+ value_uc = value.map { |s| s.upcase }
610
+ value_uc = value_uc.sort if io
611
+ end
612
+ end
619
613
 
620
- if xmsg.empty?
614
+ v_ic = do_case.call(v)
621
615
 
622
- s_name = name.is_a?(String) ? "'#{name}' " : ''
623
- xmsg = "#{param_s} #{s_name}failed validation against caller-supplied block"
624
- end
616
+ if v_ic == value_ic
625
617
 
626
- raise $!, xmsg, $!.backtrace
627
- end
618
+ case v_ic
619
+ when :string
628
620
 
629
- raise
630
- end
621
+ if value_uc == v.upcase
631
622
 
632
- if r.is_a?(::Exception)
623
+ found = true
624
+ break
625
+ end
626
+ when :array_of_strings
633
627
 
634
- # An exception returned from the block, so raise it, with
635
- # its message or a custom message
628
+ v_uc = v.map { |s| s.upcase }
629
+ v_uc = v_uc.sort if io
636
630
 
637
- x = r
638
- xmsg = x.message || ''
631
+ if value_uc == v_uc
639
632
 
640
- if xmsg.empty?
633
+ found = true
634
+ break
635
+ end
636
+ end
637
+ end
638
+ elsif io
641
639
 
642
- xmsg ||= message
640
+ unless value_io
643
641
 
644
- if xmsg.empty?
642
+ value_io = value.sort
643
+ end
645
644
 
646
- s_name = name.is_a?(String) ? "'#{name}' " : ''
647
- xmsg = "#{param_s} #{s_name}failed validation against caller-supplied block"
648
- end
645
+ if ::Array === v
649
646
 
650
- raise x, xmsg
651
- end
647
+ v_io = v.sort
652
648
 
653
- raise x
649
+ if value_io == v_io
654
650
 
655
- elsif !r
651
+ found = true
652
+ break
653
+ end
654
+ end
655
+ end
656
+ end
656
657
 
657
- failed_check = true
658
+ unless found
658
659
 
659
- unless options[:nothrow]
660
+ failed_check = true
660
661
 
661
- s_name = name.is_a?(String) ? "'#{name}' " : ''
662
- xmsg = "#{param_s} #{s_name}failed validation against caller-supplied block"
662
+ unless options[:nothrow]
663
663
 
664
- if value.is_a?(::Numeric)
664
+ unless message
665
665
 
666
- raise RangeError, xmsg
667
- else
666
+ s_name = name.is_a?(String) ? "'#{name}' " : ''
668
667
 
669
- raise ArgumentError, xmsg
670
- end
671
- end
668
+ message = "#{param_s} #{s_name}value '#{value}' not found equal/within any of required values or ranges"
669
+ end
672
670
 
673
- elsif r.is_a?(::TrueClass)
671
+ if value.is_a?(::Numeric)
674
672
 
675
- ;
676
- else
673
+ raise RangeError, message
674
+ else
677
675
 
678
- return_value = r
679
- end
680
- end
676
+ raise ArgumentError, message
677
+ end
678
+ end
679
+ end
680
+ end
681
681
 
682
- failed_check ? nil : return_value
683
- end
682
+ failed_check ? nil : value
683
+ end
684
684
 
685
685
  end # module ParameterChecking
686
686
 
@@ -689,4 +689,3 @@ end # module Xqsr3
689
689
 
690
690
  # ############################## end of file ############################# #
691
691
 
692
-