ensure_it 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: 3327ef9e83c77e8983afebc84649fa8dbcfa9539
4
- data.tar.gz: b7197ebaf1daf96979bd0192d6c0fc5f7d0ba95d
3
+ metadata.gz: 5ba3443d9d913fa270efaafb09ed62ff942ccb97
4
+ data.tar.gz: 1748051d5985f1a9ae54f9eec83d7fd70666695a
5
5
  SHA512:
6
- metadata.gz: 95223df056bfecb587411ca19861cb87dd7d1c84188e886343be34fb02e597ef716d88d97e1e542d86cb4d4702ec9cc139f464d04b323a25085a665c9cbd9cfa
7
- data.tar.gz: ad75c0c7d19b5f58f0d10e58db0179b9a23ec347a8dd66f12e68d059b475692ccc72ecef4b32ccc6a47284e740f1475dd9f30b5eaed111ae2e4dc46d01a61d89
6
+ metadata.gz: a7c50aa22687707d9ab0940aa8bc66bb5dc90c7da4ede7790f99437359acfed6846bf3ece8dfc23fa4c91afaf1ca1a3d6e9c1e88a8746bf5aca18f9dde96c862
7
+ data.tar.gz: f998fe70c88c0660373d53faa54a4c6076b3c5bd34c7bf3db4a28cf3598c449ebc9523ae9fa39b7f50c923d582515efa8315affdc0526726e342d9a5a3bc4d50
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
+ .ruby-version
6
7
  Gemfile.lock
7
8
  InstalledFiles
8
9
  _yardoc
data/.travis.yml CHANGED
@@ -4,7 +4,7 @@ rvm:
4
4
  - 2.1.1
5
5
  - ruby-head
6
6
  env:
7
- - USE_REFINES=true USE_COVERALLS=true
8
- - USE_REFINES=true USE_COVERALLS=false
9
- - USE_REFINES=false USE_COVERALLS=true
10
- - USE_REFINES=false USE_COVERALLS=false
7
+ - USE_REFINES=true
8
+ - USE_REFINES=false
9
+ # - USE_REFINES=false USE_COVERALLS=true
10
+ # - USE_REFINES=false USE_COVERALLS=false
data/Gemfile CHANGED
@@ -3,4 +3,6 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in ensure_it.gemspec
4
4
  gemspec
5
5
 
6
- gem 'coveralls', require: false
6
+ group :test do
7
+ gem 'coveralls', require: false
8
+ end
data/README.md CHANGED
@@ -5,24 +5,54 @@
5
5
 
6
6
  # EnsureIt
7
7
 
8
- This library provides way to check and converts local variables for every-method usage, like arguments checking.
8
+ This library provides way to check and convert local variables for every-method usage, like arguments checking.
9
9
 
10
10
  The main goal of EnsureIt is to provide as fast executed code as it possible with simple and usable syntax.
11
11
 
12
12
  > **Note:** this library doesn't support ruby older than `2.0.0`
13
13
 
14
+ The simplest example, that you can find at `examples/symbol.rb`:
15
+
16
+ ```ruby
17
+ require 'rubygems'
18
+ require 'bundler/setup'
19
+ require 'ensure_it'
20
+
21
+ def test(arg)
22
+ arg.ensure_symbol!
23
+ end
24
+
25
+ puts test(:symbol).inspect
26
+ puts test('string').inspect
27
+ puts test(0).inspect
28
+ ```
29
+
30
+ gives following output:
31
+
32
+ ```
33
+ $ ruby examples/symbol.rb
34
+ :symbol
35
+ :string
36
+ examples/symbol.rb:6:in `test': argument 'arg' of 'test' method should be a Symbol or a String (EnsureIt::Error)
37
+ from examples/symbol.rb:11:in `<main>'
38
+ ```
39
+
40
+ At first, string converted to symbol.
41
+
42
+ Secondary, note on error message. The library magically recognizes that `ensure_symbol!` called for `arg` argument of `test` method.
43
+
14
44
  ## Installation
15
45
 
16
46
  Add this line to your application's Gemfile:
17
47
 
18
48
  ```ruby
19
- gem 'ensure_it'
49
+ gem 'ensure_it'
20
50
  ```
21
51
 
22
52
  or for [refinements](#refinements) version:
23
53
 
24
54
  ```ruby
25
- gem 'ensure_it', require: 'ensure_it_refines'
55
+ gem 'ensure_it', require: 'ensure_it_refined'
26
56
  ```
27
57
 
28
58
  And then execute:
@@ -39,7 +69,7 @@ $ gem install ensure_it
39
69
 
40
70
  ## Configuration
41
71
 
42
- For this moment only one configuration option available - global setting of smart errors (see [Usage section](usage)):
72
+ For this moment only one configuration option available - global setting of smart errors (see [Usage section](#usage)):
43
73
 
44
74
  ```ruby
45
75
  require 'ensure_it'
@@ -52,11 +82,11 @@ end
52
82
 
53
83
  ## Usage
54
84
 
55
- EnsureIt does monkey-patching or provides refines (see [Refinements section](#refinements)) for general ruby objects with set of `ensure_*` methods. So you can call this methods with everything in ruby. Corresponding to method name it returns `nil` (or raise exception for bang version of method, that name ended with `!`) for unusual or impossible type conversions and returns object of ensured type if conversion is possible.
85
+ EnsureIt does monkey-patching or provides refines (see [Refinements section](#refinements)) for generic ruby objects with set of `ensure_*` methods. So you can call this methods with everything in ruby. Corresponding to method name it returns `nil` (or raise exception for bang version of method, that name ended with `!`) for unusual or impossible type conversions and returns object of ensured type if conversion is possible.
56
86
 
57
87
  For example `ensure_symbol` method returns symbol itself for Symbols, converted to symbol value for Strings and nil for all other. Same way `ensure_symbol!` returns symbol for String and Symbol, and raises exception for all other.
58
88
 
59
- The special thing, that EnsureIt can do (and do it by default) is smart error messages in bang methods. In most cases, EnsureIt guesses right context in wich `ensure_*` method called and froms more informative message. It recognizes name of local variable if method called for variable like `my_var.ensure_symbol`, argument name, if variable is argument of method and method calls itself like `'some_string'.to_sym.ensure_symbol` - so `ensure_symbol` called on result of `to_sym` method. You can disable this functionality at all (see [Configuration section](configuration)) or override globally configuration for any method call by `smart` option like this `:symbol.ensure_symbol(smart: true)` or `:symbol.ensure_symbol(smart: false)`. In any way, this `:smart` errors doesn't affect execution speed because the analyzing block of code executed only on exception - not on every `ensure_*` call.
89
+ The special thing, that EnsureIt can do (and do it by default) is smart error messages in bang methods. In most cases, EnsureIt guesses right context in wich `ensure_*` method called and froms more informative message. It recognizes name of local variable if method called for variable like `my_var.ensure_symbol`, argument name, if variable is argument of method and method calls itself like `'some_string'.to_sym.ensure_symbol` - so `ensure_symbol` called on result of `to_sym` method. You can disable this functionality at all (see [Configuration section](#configuration)) or override globally configuration for any method call by `smart` option like this `:symbol.ensure_symbol(smart: true)` or `:symbol.ensure_symbol(smart: false)`. In any way, this `:smart` errors doesn't affect execution speed because the analyzing block of code executed only on exception - not on every `ensure_*` call.
60
90
 
61
91
  For example, following code
62
92
 
@@ -84,7 +114,7 @@ end
84
114
  awesome(0)
85
115
  ```
86
116
 
87
- will produce ArgumentError with message `it's unusual that 'arg' of 'awesome' method with name arg is not a symbol. Raised in ensure_symbol!`.
117
+ will produce ArgumentError with message `it's bad that 'arg' of 'awesome' method with name arg is not a symbol. Raised in ensure_symbol!`.
88
118
 
89
119
  ### ensure_symbol, ensure_symbol!
90
120
 
@@ -94,6 +124,10 @@ Returns self for Symbol, converted value for String, nil (or raise) for other:
94
124
  :test.ensure_symbol # => :test
95
125
  'test'.ensure_symbol # => :test
96
126
  100.ensure_symbol # => nil
127
+ :test.esnure_symbol(values: %i(one two)) # => nil
128
+ :one.esnure_symbol(values: %i(one two)) # => :one
129
+ 'test'.esnure_symbol(values: %i(one two)) # => nil
130
+ 'one'.esnure_symbol(values: %i(one two)) # => :one
97
131
  ```
98
132
 
99
133
  ### ensure_string, ensure_string!
@@ -153,7 +187,7 @@ By default, returns Array only for Array itself and **empty** array (not nil) fo
153
187
  ```ruby
154
188
  [1, nil, 2].ensure_array # => [1, nil, 2]
155
189
  true.ensure_array # => []
156
- true.ensure_array(wrong: nil) # => nil
190
+ true.ensure_array(default: nil) # => nil
157
191
  [1, nil, 2].ensure_array(compact: true) # => [1, 2]
158
192
  [1, [2, 3], 4].ensure_array(flatten: true) # => [1, 2, 3, 4]
159
193
  [1, [5, 6], 4].ensure_array(flatten: true, sorted: true) # => [1, 4, 5, 6]
@@ -224,11 +258,17 @@ Array.ensure_class(Enumerable, CustomModule) # => nil
224
258
  Array.ensure_class(Enumerable) # => Array
225
259
  ```
226
260
 
261
+ ### Common options for all methods
262
+
263
+ |option|possible values|meaning|
264
+ |------|---------------|-------|
265
+ |`:values`|Array|(not used in `ensure_instance_of` and `ensure_hash`) an array of possible values. If value doesn't included in this array, default value returned or exception raised for bang methods. Note that library doesn't check types of this array elements, so be sure to specify array with right elements here.
266
+
227
267
  ### Common options for all non-bang methods
228
268
 
229
269
  |option|possible values|meaning|
230
270
  |------|---------------|-------|
231
- |`:wrong`|any|if present then will be used as wrong value instead of default `nil`|
271
+ |`:default`|any|if present then will be used as wrong value|
232
272
 
233
273
  ### Common options for all bang methods
234
274
 
@@ -242,23 +282,23 @@ Array.ensure_class(Enumerable) # => Array
242
282
 
243
283
  Since ruby `2.0.0` [refinements](http://www.ruby-doc.org/core-2.1.1/doc/syntax/refinements_rdoc.html) mechanism intorduced and was experimental till `2.1.0`. Starting from `2.1.0` you can use it without warnings and in module and class scope.
244
284
 
245
- EnsureIt is fully tested and working with refinements. But not by default and not for ruby `< 2.1.0`. To use refined version of EnsureIt (with zero-monkey-pathing) just require `ensure_it_refines` instead of `ensure_it`. If you use bundler, you can do it, by specifying `require: 'ensure_it_refines'` option for `gem 'ensure_it'` in your `Gemfile`:
285
+ EnsureIt is fully tested and working with refinements. But not by default and not for ruby `< 2.1.0`. To use refined version of EnsureIt (with zero-monkey-pathing) just require `ensure_it_refined` instead of `ensure_it`. If you use bundler, you can do it, by specifying `require: 'ensure_it_refined'` option for `gem 'ensure_it'` in your `Gemfile`:
246
286
 
247
287
  ```ruby
248
- gem 'ensure_it', require: 'ensure_it_refines'
288
+ gem 'ensure_it', require: 'ensure_it_refined'
249
289
  ```
250
290
 
251
291
  Or without bundler:
252
292
 
253
293
  ```ruby
254
294
  # In you code initialization
255
- require 'ensure_it_refines'
295
+ require 'ensure_it_refined'
256
296
  ```
257
297
 
258
298
  Then activate EnsureIt refines by `using EnsureIt` in needed scope:
259
299
 
260
300
  ```ruby
261
- require 'ensure_it_refines'
301
+ require 'ensure_it_refined'
262
302
 
263
303
  class AwesomeClass
264
304
  using EnsureIt
@@ -275,8 +315,68 @@ AwesomeClass.new.awesome_method(0) # => raises EnsureIt::Error with message
275
315
 
276
316
  Please read carefully [refinements](http://www.ruby-doc.org/core-2.1.1/doc/syntax/refinements_rdoc.html) documentation before using refined EnsureIt. Don't forget to call `using EnsureIt` in every file (not class or method if your class or method placed in many files) you need it.
277
317
 
318
+ ## Benchmarking
319
+
320
+ In development mode a set of thor tasks under 'ensure_it:benchmark' namespace provided for benchmarking and profiling any library method. Also tasks `:non_bang`, `:bang` and `:all` provided for benchmarking all non-bang methods, all bang methods and allmost all methods respectively. To benchmark refined version of library, use `USE_REFINES=true` environment variable.
321
+
322
+ ```sh
323
+ thor ensure_it:benchmark:symbol # benchmark #ensure_symbol method
324
+ thor ensure_it:benchmark:symbol! # benchmark #ensure_symbol! method
325
+ thor ensure_it:benchmark:non_bang # benchmark all non-bang methods
326
+ thor ensure_it:benchmark:all # benchmark all library methods
327
+ USE_REFINES=true thor ensure_it:benchmark:all # benchmark refined library
328
+ ```
329
+
330
+ Some results on my machine:
331
+
332
+ ```
333
+ $ thor ensure_it:benchmark:symbol
334
+ Starting benchmarks for #ensure_symbol with monkey-patched version of EnsureIt. Errors: standard. Ruby version: 2.1.1
335
+ ensure_it: 0.090000 0.000000 0.090000 ( 0.083292)
336
+ standard way: 0.050000 0.000000 0.050000 ( 0.051999)
337
+
338
+ $ thor ensure_it:benchmark:symbol!
339
+ Starting benchmarks for #ensure_symbol! with monkey-patched version of EnsureIt. Errors: standard. Ruby version: 2.1.1
340
+ ensure_it: 6.350000 0.000000 6.350000 ( 6.431325)
341
+ standard way: 0.440000 0.000000 0.440000 ( 0.435714)
342
+ ```
343
+
344
+ As you can see, call to `#esnure_symbol` is very close to standard type checking (number of benchmark runs - 10000), but bang version consumes much more time. This because we need to do some job to grab information from code for error message. And, of course, this code will execute only when error occured. Call to bang method for expected values (Symbols and Strings in this case) consume same time, as for normal `#ensure_symbol`.
345
+
346
+ Some options available for benchmarking.
347
+
348
+ ### profiling
349
+ `-p` or `--profile=true` or `--profile=/ouput/dir`. Turns on profiling. If you specify profiling as boolean option, all progiling output will be putted into tmp dir under library root.
350
+
351
+ ```sh
352
+ thor ensure_it:benchmark:symbol -p # benchmark and profile #ensure_symbol
353
+ thor ensure_it:benchmark:symbol --profile=/tmp/emsure_it
354
+ ```
355
+
356
+ ### number of examples
357
+ `-n` or `--number`. By default, all benchmarking procs runs 10000 times. You can specify another value with this option.
358
+
359
+ ```sh
360
+ thor ensure_it:benchmark:all -n 1000
361
+ ```
362
+
363
+ ### smart errors
364
+ `-s` or `smart=true`. By default smart errors are off for time consuming. You can turn it on by this option.
365
+
366
+ ```sh
367
+ thor ensure_it:benchmark:all -n 1000 -s
368
+ ```
369
+
278
370
  ## Changelog
279
371
 
372
+ `0.1.2`
373
+ * smart errors refactored
374
+ * benchmarking added
375
+ * `wrong` option changed to `default`
376
+ * `values` option added
377
+ * a lot of code refactored
378
+ * `ensure_it_refines` changed to `ensure_it_refined`
379
+
280
380
  `0.1.1`
281
381
  * fixed: no error_class in standard errors mode
282
382
 
@@ -297,15 +397,19 @@ Please read carefully [refinements](http://www.ruby-doc.org/core-2.1.1/doc/synta
297
397
 
298
398
  ## Todo
299
399
 
300
- * enlarge method set
400
+ * class from string converting for ensure_class
401
+ * ensure_file_name
402
+ * ensure_var_name
301
403
  * enlarge number of options for arrays and hashes
302
404
  * block processing for arrays and hashes
303
- * benchmarking and profiling
405
+ * rspec matchers
406
+ * ActiveSupport and MongoId integration
304
407
  * custom extending functionality support
408
+ * profiling distribution
305
409
 
306
410
  ## Contributing
307
411
 
308
- 1. Fork it ( http://github.com/<my-github-username>/skeleton/fork )
412
+ 1. Fork it (http://github.com/cybernetlab/ensure_it/fork)
309
413
  2. Create your feature branch (`git checkout -b my-new-feature`)
310
414
  3. Commit your changes (`git commit -am 'Add some feature'`)
311
415
  4. Push to the branch (`git push origin my-new-feature`)
data/ensure_it.gemspec CHANGED
@@ -36,4 +36,7 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency 'redcarpet', '~> 3.1'
37
37
  spec.add_development_dependency 'yard', '~> 0.8'
38
38
  spec.add_development_dependency 'rspec', '~> 2.14'
39
+ spec.add_development_dependency 'coveralls', '~> 0.7'
40
+ spec.add_development_dependency 'thor', '~> 0.18'
41
+ spec.add_development_dependency 'ruby-prof', '~> 0.14'
39
42
  end
@@ -0,0 +1,11 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'ensure_it'
4
+
5
+ def test(arg)
6
+ arg.ensure_symbol!
7
+ end
8
+
9
+ puts test(:symbol).inspect
10
+ puts test('string').inspect
11
+ puts test(0).inspect
@@ -1,20 +1,20 @@
1
1
  module EnsureIt
2
2
  patch Object do
3
- def ensure_array(*args, **opts)
4
- opts.key?(:wrong) ? opts[:wrong] : []
3
+ def ensure_array(*args, default: [], **opts)
4
+ default
5
5
  end
6
6
 
7
- def ensure_array!(*args, **opts)
7
+ def ensure_array!(*args, default: nil, **opts)
8
8
  opts[:message] ||= '#{subject} should be an Array'
9
9
  EnsureIt.raise_error(:ensure_array!, **opts)
10
10
  end
11
11
  end
12
12
 
13
13
  patch Array do
14
- using EnsureIt if ENSURE_IT_REFINES
14
+ using EnsureIt if ENSURE_IT_REFINED
15
15
 
16
- if ENSURE_IT_REFINES
17
- def ensure_array(*args, **opts)
16
+ if ENSURE_IT_REFINED
17
+ def ensure_array(*args, values: nil, **opts)
18
18
  arr = self
19
19
  args.each do |arg|
20
20
  arg = arg.ensure_symbol || next
@@ -39,6 +39,7 @@ module EnsureIt
39
39
  return arr if opts.empty?
40
40
  arr = arr.map { |x| x } if arr == self
41
41
  arr.flatten! if opts[:flatten] == true
42
+ arr.select! { |x| values.include?(x) } if values.is_a?(Array)
42
43
  opts[:sorted] ||= opts.delete(:ordered) if opts.key?(:ordered)
43
44
  arr.sort! if opts.key?(:sorted)
44
45
  arr.reverse! if opts[:sorted].ensure_symbol == :desc
@@ -46,7 +47,7 @@ module EnsureIt
46
47
  arr
47
48
  end
48
49
  else
49
- def ensure_array(*args, **opts)
50
+ def ensure_array(*args, values: nil, **opts)
50
51
  arr = self
51
52
  args.each do |arg|
52
53
  arg = arg.ensure_symbol || next
@@ -55,6 +56,7 @@ module EnsureIt
55
56
  return arr if opts.empty?
56
57
  arr = arr.map { |x| x } if arr == self
57
58
  arr.flatten! if opts[:flatten] == true
59
+ arr.select! { |x| values.include?(x) } if values.is_a?(Array)
58
60
  opts[:sorted] ||= opts.delete(:ordered) if opts.key?(:ordered)
59
61
  arr.sort! if opts.key?(:sorted)
60
62
  arr.reverse! if opts[:sorted].ensure_symbol == :desc
@@ -1,26 +1,32 @@
1
1
  module EnsureIt
2
2
  patch Object do
3
- def ensure_class(*args, **opts)
4
- opts.key?(:wrong) ? opts[:wrong] : nil
3
+ def ensure_class(*args, default: nil, **opts)
4
+ default
5
5
  end
6
6
 
7
- def ensure_class!(*args, **opts)
7
+ def ensure_class!(*args, default: nil, **opts)
8
8
  opts[:message] ||= '#{subject} should be a class'
9
9
  EnsureIt.raise_error(:ensure_class!, **opts)
10
10
  end
11
11
  end
12
12
 
13
13
  patch Class do
14
- using EnsureIt if ENSURE_IT_REFINES
15
-
16
- def ensure_class(*args, **opts)
14
+ def ensure_class(*args, default: nil, values: nil, **opts)
17
15
  args.select! { |x| x.is_a?(Module) }
18
- args.all? { |x| self <= x } ? self : super(**opts)
16
+ return default unless args.all? { |x| self <= x }
17
+ if values.nil? || values.is_a?(Array) && values.include?(self)
18
+ self
19
+ else
20
+ default
21
+ end
19
22
  end
20
23
 
21
- def ensure_class!(*args, **opts)
24
+ def ensure_class!(*args, default: nil, values: nil, **opts)
22
25
  args.select! { |x| x.is_a?(Module) }
23
- return self if args.all? { |x| self <= x }
26
+ if args.all? { |x| self <= x } &&
27
+ (values.nil? || values.is_a?(Array) && values.include?(self))
28
+ return self
29
+ end
24
30
  args = args.map!(&:name).join(', ')
25
31
  opts[:message] ||=
26
32
  "\#{subject} should subclass or extend all of ['#{args}']"
@@ -2,47 +2,104 @@ module EnsureIt
2
2
  FLOAT_REGEXP = /\A[+\-]?(?:\d+(?:\.\d*)?|\d*\.\d+)(?:[eE][+\-]?\d+)?\z/
3
3
 
4
4
  patch Object do
5
- def ensure_float(**opts)
6
- opts.key?(:wrong) ? opts[:wrong] : nil
5
+ def ensure_float(default: nil, **opts)
6
+ default
7
7
  end
8
8
 
9
- def ensure_float!(**opts)
10
- opts[:message] ||= '#{subject} should be a float or be able' \
11
- ' to convert to it'
12
- EnsureIt.raise_error(:ensure_float!, **opts)
9
+ def ensure_float!(default: nil, **opts)
10
+ EnsureIt.raise_error(
11
+ :ensure_float!,
12
+ **EnsureIt::ensure_float_error_options(**opts)
13
+ )
13
14
  end
14
15
  end
15
16
 
16
17
  patch String do
17
- using EnsureIt if ENSURE_IT_REFINES
18
-
19
- def ensure_float(**opts)
20
- self =~ FLOAT_REGEXP ? to_f : nil
18
+ def ensure_float(default: nil, values: nil, **opts)
19
+ return default unless self =~ FLOAT_REGEXP
20
+ value = to_f
21
+ if values.nil? || values.is_a?(Array) && values.include?(value)
22
+ value
23
+ else
24
+ default
25
+ end
21
26
  end
22
27
 
23
- def ensure_float!(**opts)
24
- ensure_float(**opts) || super(**opts)
28
+ def ensure_float!(default: nil, values: nil, **opts)
29
+ if self =~ FLOAT_REGEXP
30
+ value = to_f
31
+ if values.nil? || values.is_a?(Array) && values.include?(value)
32
+ return value
33
+ end
34
+ end
35
+ EnsureIt.raise_error(
36
+ :ensure_float!,
37
+ **EnsureIt::ensure_float_error_options(**opts)
38
+ )
25
39
  end
26
40
  end
27
41
 
28
42
  patch Integer do
29
- def ensure_float(**opts)
30
- to_f
43
+ def ensure_float(default: nil, values: nil, **opts)
44
+ return to_f if values.nil?
45
+ value = to_f
46
+ values.is_a?(Array) && values.include?(value) ? value : default
47
+ end
48
+
49
+ def ensure_float!(default: nil, values: nil, **opts)
50
+ return to_f if values.nil?
51
+ value = to_f
52
+ return values if values.is_a?(Array) && values.include?(value)
53
+ EnsureIt.raise_error(
54
+ :ensure_float!,
55
+ **EnsureIt::ensure_float_error_options(**opts)
56
+ )
31
57
  end
32
- alias_method :ensure_float!, :ensure_float
33
58
  end
34
59
 
35
60
  patch Float do
36
- def ensure_float(**opts)
37
- self
61
+ def ensure_float(default: nil, values: nil, **opts)
62
+ if values.nil? || values.is_a?(Array) && values.include?(self)
63
+ self
64
+ else
65
+ default
66
+ end
67
+ end
68
+
69
+ def ensure_float!(default: nil, values: nil, **opts)
70
+ if values.nil? || values.is_a?(Array) && values.include?(self)
71
+ return self
72
+ end
73
+ EnsureIt.raise_error(
74
+ :ensure_float!,
75
+ **EnsureIt::ensure_float_error_options(**opts)
76
+ )
38
77
  end
39
- alias_method :ensure_float!, :ensure_float
40
78
  end
41
79
 
42
80
  patch Rational do
43
- def ensure_float(**opts)
44
- to_f
81
+ def ensure_float(default: nil, values: nil, **opts)
82
+ return to_f if values.nil?
83
+ value = to_f
84
+ values.is_a?(Array) && values.include?(value) ? value : default
85
+ end
86
+
87
+ def ensure_float!(default: nil, values: nil, **opts)
88
+ return to_f if values.nil?
89
+ value = to_f
90
+ return values if values.is_a?(Array) && values.include?(value)
91
+ EnsureIt.raise_error(
92
+ :ensure_float!,
93
+ **EnsureIt::ensure_float_error_options(**opts)
94
+ )
95
+ end
96
+ end
97
+
98
+ def self.ensure_float_error_options(**opts)
99
+ unless opts.key?(:message)
100
+ opts[:message] = '#{subject} should be a float or be able' \
101
+ ' to convert to it'
45
102
  end
46
- alias_method :ensure_float!, :ensure_float
103
+ opts
47
104
  end
48
105
  end
@@ -1,20 +1,20 @@
1
1
  module EnsureIt
2
2
  patch Object do
3
- def ensure_hash(*args, **opts)
4
- opts.key?(:wrong) ? opts[:wrong] : {}
3
+ def ensure_hash(*args, default: {}, **opts)
4
+ default
5
5
  end
6
6
 
7
- def ensure_hash!(*args, **opts)
7
+ def ensure_hash!(*args, default: nil, **opts)
8
8
  opts[:message] ||= '#{subject} should be a Hash'
9
9
  EnsureIt.raise_error(:ensure_hash!, **opts)
10
10
  end
11
11
  end
12
12
 
13
13
  patch Hash do
14
- using EnsureIt if ENSURE_IT_REFINES
14
+ using EnsureIt if ENSURE_IT_REFINED
15
15
 
16
16
  def ensure_hash(*args, **opts)
17
- return self if opts[:symbolize_keys] != true
17
+ return self if opts.empty? || opts[:symbolize_keys] != true
18
18
  Hash[map { |k, v| [k.ensure_symbol, v] }.reject { |x| x[0].nil? }]
19
19
  end
20
20
  alias_method :ensure_hash!, :ensure_hash
@@ -1,17 +1,16 @@
1
1
  module EnsureIt
2
2
  patch Object do
3
- def ensure_instance_of(klass, **opts)
3
+ def ensure_instance_of(klass, default: nil, **opts)
4
4
  unless klass.is_a?(Class)
5
5
  fail(
6
6
  ArgumentError,
7
7
  'Wrong class argument for #ensure_instance_of specified'
8
8
  )
9
9
  end
10
- return self if is_a?(klass)
11
- opts.key?(:wrong) ? opts[:wrong] : nil
10
+ is_a?(klass) ? self : default
12
11
  end
13
12
 
14
- def ensure_instance_of!(klass, **opts)
13
+ def ensure_instance_of!(klass, default: nil, **opts)
15
14
  unless klass.is_a?(Class)
16
15
  fail(
17
16
  ArgumentError,