constrain 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c176bf713350005e558d37a3b88b08f2a5f0ba37f0d2a829aa1d4b5dd1e8b0b4
4
- data.tar.gz: 02f69468f0130af3c702159b3cff2def10f1755916bc774e903f3d6cb8136fba
3
+ metadata.gz: c8c92be44953ded28f60341e340c7e96a8891124427efb31a06cbc94c7664cf1
4
+ data.tar.gz: 65196009ea3d69aab1174722296949977bb622a68ac16dd04320dc7816503a2e
5
5
  SHA512:
6
- metadata.gz: 5117883c01aa7658dd4adefcabb8af14c761090abb407d4141fd6f9321828d8f386f6dccba634d8e08af09bd893d8457d05495cbeba2a91f66d52af92e5c1b4e
7
- data.tar.gz: 5dc0238f65e4a6771b9a2bca452ab9eabb160c17ca32cec143a835bceb2296a317a661b7faa613a2c0148b3a3e236aef82e64351064a66b250ba146a8b9b5d36
6
+ metadata.gz: 4acb8bd66add5cb3937efdbe5272b57acac1ea1fe193df84f2ea48c3aa6a12b0a214a2832aeac7e2968871da9c226ba263dfe0ebec883ff42259d9667edfb92f
7
+ data.tar.gz: '094404002ee23266e98a58ad7ade0910d0768fa2956440ab1502c768b0fda2785c35d13821e3adb21e571198ed9eb223eac216f04b3406296c34569d71f4a874'
data/README.md CHANGED
@@ -60,30 +60,34 @@ end
60
60
  The alternative is to include the constrain Module in a common root class to
61
61
  have it available in all child class
62
62
 
63
- The #constrain method has the following signature
63
+ ## Methods
64
64
 
65
- ```ruby
66
- constrain(value, *class-expressions, message = nil)
67
- ```
65
+ #### constrain(value, \*class-expressions, message = nil, unwind: 0)
68
66
 
69
- It checks that the value matches at least one of the class-expressions
70
- and raise a Constrain::TypeError if not. The error message can be customized by
71
- added the message argument. #constrain also raise a Constrain::Error exception
72
- if there is an error in the class expression. It is typically used to
73
- type-check parameters in methods
67
+ Return the given value if it matches at least one of the class-expressions and raise a
68
+ Constrain::TypeError if not. The error message can be customized by added the
69
+ message argument and a number of backtrace leves can be skipped by setting
70
+ :unwind option. By default the backtrace will refer to the point of the call of
71
+ \#constrain. \#constrain araises a Constrain::Error exception if there is
72
+ an error in the syntax of the class expression
74
73
 
75
- Constrain also defines a #check class method with the signature
74
+ \#constrain is typically used to type-check parameters in methods where you
75
+ want an exception if the parameters doesn't match the expected, but because it
76
+ returns the value if successful it can be used to check the validity of
77
+ variables in expressions too, eg. `return constrain(result_of_complex_computation, Integer)`
78
+ to check the return value of a method
76
79
 
77
- ```ruby
78
- Constrain.check(value, *class-expression) -> true or false
79
- ```
80
+
81
+ #### Constrain.constrain?(value, \*class-expression) -> true or false
80
82
 
81
83
  It matches value against the class expressions like #constrain but returns true
82
- or false as result
84
+ or false as result and can be used to handle complex type expressions
85
+ dynamically. It is made a class method to minimize namespace pollution
86
+
83
87
 
84
88
  ## Class Expressions
85
89
 
86
- Constrain#constrain and Constrain::check use class expressions composed of
90
+ Constrain#constrain and Constrain::constrain? use class expressions composed of
87
91
  class or module objects, Proc objects, or arrays and hashes of class expressions. Class or module
88
92
  objects match if `value.is_a?(class_or_module)` returns true:
89
93
 
data/constrain.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  Constrain works with ruby-2 (and maybe ruby-3)
28
28
  }
29
- spec.homepage = "http://www.nowhere.com/"
29
+ spec.homepage = "https://github.com/clrgit/constrain/"
30
30
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
31
31
 
32
32
  spec.metadata["homepage_uri"] = spec.homepage
data/lib/constrain.rb CHANGED
@@ -6,42 +6,44 @@ module Constrain
6
6
 
7
7
  # Raised if types doesn't match a class expression
8
8
  class TypeError < Error
9
- def initialize(value, exprs, msg = nil)
9
+ def initialize(value, exprs, msg = nil, unwind: 0)
10
10
  super msg || "Expected #{value.inspect} to match #{Constrain.fmt_exprs(exprs)}"
11
11
  end
12
12
  end
13
13
 
14
14
  # Check that value matches one of the class expressions. Raises a
15
15
  # Constrain::Error if the expression is invalid and a Constrain::TypeError if
16
- # the value doesn't match
17
- def constrain(value, *exprs)
16
+ # the value doesn't match. The exception's backtrace skips :unwind number of entries
17
+ def constrain(value, *exprs, unwind: 0)
18
18
  msg = exprs.pop if exprs.last.is_a?(String)
19
19
  begin
20
20
  !exprs.empty? or raise Error, "Empty class expression"
21
- exprs.any? { |expr| Constrain.check(value, expr) } or raise TypeError.new(value, exprs, msg)
21
+ exprs.any? { |expr| Constrain.constrain?(value, expr) } or
22
+ raise TypeError.new(value, exprs, msg, unwind: unwind)
22
23
  rescue Error => ex
23
- ex.set_backtrace(caller[1..-1])
24
+ ex.set_backtrace(caller[1 + unwind..-1])
24
25
  raise
25
26
  end
27
+ value
26
28
  end
27
29
 
28
30
  # Return true if the value matches the class expression. Raises a
29
31
  # Constrain::Error if the expression is invalid
30
- def self.check(value, expr)
32
+ def self.constrain?(value, expr)
31
33
  case expr
32
34
  when Class, Module
33
35
  value.is_a?(expr)
34
36
  when Array
35
37
  !expr.empty? or raise Error, "Empty array"
36
- value.is_a?(Array) && value.all? { |elem| expr.any? { |e| check(elem, e) } }
38
+ value.is_a?(Array) && value.all? { |elem| expr.any? { |e| constrain?(elem, e) } }
37
39
  when Hash
38
40
  value.is_a?(Hash) && value.all? { |key, value|
39
41
  expr.any? { |key_expr, value_expr|
40
42
  [[key, key_expr], [value, value_expr]].all? { |value, expr|
41
43
  if expr.is_a?(Array) && (expr.size > 1 || expr.first.is_a?(Array))
42
- expr.any? { |e| check(value, e) }
44
+ expr.any? { |e| constrain?(value, e) }
43
45
  else
44
- check(value, expr)
46
+ constrain?(value, expr)
45
47
  end
46
48
  }
47
49
  }
@@ -1,3 +1,3 @@
1
1
  module Constrain
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: constrain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-17 00:00:00.000000000 Z
11
+ date: 2021-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simplecov
@@ -52,10 +52,10 @@ files:
52
52
  - constrain.gemspec
53
53
  - lib/constrain.rb
54
54
  - lib/constrain/version.rb
55
- homepage: http://www.nowhere.com/
55
+ homepage: https://github.com/clrgit/constrain/
56
56
  licenses: []
57
57
  metadata:
58
- homepage_uri: http://www.nowhere.com/
58
+ homepage_uri: https://github.com/clrgit/constrain/
59
59
  post_install_message:
60
60
  rdoc_options: []
61
61
  require_paths: