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 +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +4 -4
- data/Gemfile +3 -1
- data/README.md +120 -16
- data/ensure_it.gemspec +3 -0
- data/examples/symbol.rb +11 -0
- data/lib/ensure_it/ensure_array.rb +9 -7
- data/lib/ensure_it/ensure_class.rb +15 -9
- data/lib/ensure_it/ensure_float.rb +78 -21
- data/lib/ensure_it/ensure_hash.rb +5 -5
- data/lib/ensure_it/ensure_instance_of.rb +3 -4
- data/lib/ensure_it/ensure_integer.rb +109 -38
- data/lib/ensure_it/ensure_string.rb +70 -21
- data/lib/ensure_it/ensure_symbol.rb +56 -11
- data/lib/ensure_it/errors.rb +22 -27
- data/lib/ensure_it/patch.rb +1 -1
- data/lib/ensure_it/version.rb +1 -1
- data/lib/ensure_it.rb +1 -1
- data/lib/{ensure_it_refines.rb → ensure_it_refined.rb} +2 -2
- data/lib/tasks/ensure_it_benchmark.thor +243 -0
- data/spec/integration/refines_spec.rb +11 -11
- data/spec/lib/ensure_array_spec.rb +4 -4
- data/spec/lib/ensure_class_spec.rb +4 -3
- data/spec/lib/ensure_float_spec.rb +3 -1
- data/spec/lib/ensure_hash_spec.rb +4 -4
- data/spec/lib/ensure_instance_of_spec.rb +3 -3
- data/spec/lib/ensure_integer_spec.rb +3 -1
- data/spec/lib/ensure_string_spec.rb +3 -1
- data/spec/lib/ensure_symbol_spec.rb +18 -1
- data/spec/lib/errors_spec.rb +17 -4
- data/spec/lib/patch_spec.rb +1 -1
- data/spec/spec_helper.rb +13 -13
- data/spec/support/example_groups/ensure_it_example_group.rb +0 -17
- data/spec/support/shared_examples/unmet_objects.rb +20 -2
- metadata +63 -20
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba3443d9d913fa270efaafb09ed62ff942ccb97
|
4
|
+
data.tar.gz: 1748051d5985f1a9ae54f9eec83d7fd70666695a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7c50aa22687707d9ab0940aa8bc66bb5dc90c7da4ede7790f99437359acfed6846bf3ece8dfc23fa4c91afaf1ca1a3d6e9c1e88a8746bf5aca18f9dde96c862
|
7
|
+
data.tar.gz: f998fe70c88c0660373d53faa54a4c6076b3c5bd34c7bf3db4a28cf3598c449ebc9523ae9fa39b7f50c923d582515efa8315affdc0526726e342d9a5a3bc4d50
|
data/.gitignore
CHANGED
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
|
8
|
-
- USE_REFINES=
|
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
data/README.md
CHANGED
@@ -5,24 +5,54 @@
|
|
5
5
|
|
6
6
|
# EnsureIt
|
7
7
|
|
8
|
-
This library provides way to check and
|
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
|
-
|
49
|
+
gem 'ensure_it'
|
20
50
|
```
|
21
51
|
|
22
52
|
or for [refinements](#refinements) version:
|
23
53
|
|
24
54
|
```ruby
|
25
|
-
|
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
|
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
|
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(
|
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
|
-
|`:
|
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 `
|
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: '
|
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 '
|
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 '
|
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
|
-
*
|
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
|
-
*
|
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 (
|
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
|
data/examples/symbol.rb
ADDED
@@ -1,20 +1,20 @@
|
|
1
1
|
module EnsureIt
|
2
2
|
patch Object do
|
3
|
-
def ensure_array(*args, **opts)
|
4
|
-
|
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
|
14
|
+
using EnsureIt if ENSURE_IT_REFINED
|
15
15
|
|
16
|
-
if
|
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
|
-
|
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
|
-
|
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 }
|
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
|
-
|
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
|
-
|
5
|
+
def ensure_float(default: nil, **opts)
|
6
|
+
default
|
7
7
|
end
|
8
8
|
|
9
|
-
def ensure_float!(**opts)
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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,
|