mixture 0.3.1 → 0.3.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: 5ab32fefd14e5972a0071d69fb66f9156f91646c
4
- data.tar.gz: 5fbffe97e27bf69ff078396dd05e48f7342fde40
3
+ metadata.gz: 5c8c8801295aa86e683119fa365df2fd15c80816
4
+ data.tar.gz: e9ec965a80f069d50e50b1997d13e1f5dab3d978
5
5
  SHA512:
6
- metadata.gz: 89592f7b40701da4b53fdba900626ec16fda88d532e97acc9af67053427c95bf6952fd3131e731c594008547a6401e4c2ad8ae2e0e77ad6cef12a88eddacb205
7
- data.tar.gz: 1e94eb32b2acf05935a1c5adcbaf7b9ae1c2f3d5c04790ed13800bf9aee699f48091b044f44a5df63bec835bf0d2cc815744b89d41069f739725976b0add878e
6
+ metadata.gz: a3423a7c7d910fbf8e70e51b8fc22505774e9f6b6de60d063e29cbfaba7f8652b4d0c455c00994a5661e2167fe509417154255ebaf01a3ca2ee05a8b740064aa
7
+ data.tar.gz: 26d4de5767aebb91b9ff0669d3dab43a5f0bcc70aa0e100d8c071cdec64a39c2b55617da06643cb41624fb430ff76933f5ba5a89962befc27ad807a5980f8c52
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mixture (0.3.1)
4
+ mixture (0.3.2)
5
5
  thread_safe (~> 0.3)
6
6
 
7
7
  GEM
@@ -125,12 +125,13 @@ module Mixture
125
125
  # @raise [CoercionError] If it could not find the coercion.
126
126
  # @return [Proc{(Object) => Object}]
127
127
  def to(type)
128
- method_name = self.class.coercions.fetch(type) do
129
- fail CoercionError, "Undefined coercion #{self.class.type} " \
130
- "=> #{type}" unless method_name
131
- end
128
+ coercions = self.class.coercions
129
+ coercable = type.inheritable
130
+ .find { |ancestor| coercions.key?(ancestor) }
131
+ fail CoercionError, "Undefined coercion #{self.class.type} " \
132
+ "=> #{type}" unless coercable
132
133
 
133
- public_send(method_name)
134
+ public_send(coercions[coercable])
134
135
  end
135
136
  end
136
137
  end
@@ -43,9 +43,9 @@ module Mixture
43
43
  # The type to coerce to.
44
44
  # @return [Proc{(Object, Mixture::Types::Object) => Object}]
45
45
  def self.coerce(from, to)
46
- coercers
47
- .fetch(from) { fail CoercionError, "No coercer for #{from}" }
48
- .to(to)
46
+ type = from.inheritable.find { |ancestor| coercers.key?(ancestor) }
47
+ fail CoercionError, "No coercer for #{from}" unless type
48
+ coercers[type].to(to)
49
49
  end
50
50
 
51
51
  # Performs the actual coercion, since blocks require a value and
@@ -15,8 +15,9 @@ module Mixture
15
15
  # @param subs [Object] The subtypes to use.
16
16
  # @return [Class] The new subtype.
17
17
  def [](*subs)
18
- options[:types].fetch([self, subs]) do
19
- create(subs)
18
+ inferred = infer_subs(subs)
19
+ options[:types].fetch([self, inferred]) do
20
+ create(inferred)
20
21
  end
21
22
  end
22
23
 
@@ -27,18 +28,25 @@ module Mixture
27
28
  # options, it doesn't infer the type of each subtype; otherwise,
28
29
  # it does.
29
30
  #
30
- # @param subs [Array<Object>] The subtypes.
31
+ # @param inferred [Array<Object>] The subtypes.
31
32
  # @return [Class] The new subtype.
32
- def create(subs)
33
+ def create(inferred)
33
34
  subtype = ::Class.new(self)
34
- members = if options[:noinfer]
35
- subs
36
- else
37
- subs.map { |sub| Types.infer(sub) }
38
- end
39
- name = "#{inspect}[#{members.join(', ')}]"
40
- subtype.options.merge!(members: members, name: name)
41
- options[:types][[self, subs]] = subtype
35
+ name = "#{inspect}[#{inferred.join(', ')}]"
36
+ subtype.options.merge!(members: inferred, name: name)
37
+ options[:types][[self, inferred]] = subtype
38
+ end
39
+
40
+ # Infers the subtypes, if the `:noinfer` option is not set.
41
+ #
42
+ # @param subs [Array<Object>] The subtypes to infer.
43
+ # @return [Array<Object>] The inferred subtypes.
44
+ def infer_subs(subs)
45
+ if options[:noinfer]
46
+ subs
47
+ else
48
+ subs.map { |sub| Types.infer(sub) }
49
+ end
42
50
  end
43
51
  end
44
52
  end
@@ -10,6 +10,21 @@ module Mixture
10
10
  options[:method] = :to_object
11
11
  as :object
12
12
 
13
+ # This, like {Type.inheritable}, provides a list of inheritable
14
+ # coercions; however, by default, if the requesting type isn't
15
+ # an Object, it _also_ leaves out the Object type; this is so
16
+ # that types that are incompatible with another type all the way
17
+ # up to the Object don't end up getting coerced incorrectly.
18
+ #
19
+ # @return [Array<Class>]
20
+ def self.inheritable
21
+ if self == Object
22
+ super
23
+ else
24
+ ancestors - Object.ancestors
25
+ end
26
+ end
27
+
13
28
  constraint do |value|
14
29
  # This may seem a bit odd, but this returns false for
15
30
  # BasicObject; and since this is meant to represent Objects,
@@ -66,40 +66,13 @@ module Mixture
66
66
  end
67
67
  end
68
68
 
69
- # Determines if this type is equal to another type. This is
70
- # used by Ruby's hash, and is used to make an anonymous type
71
- # equal to its supertype (e.g.
72
- # `Types::Array[Types::Integer] == Types::Array`), mainly for
73
- # coercion.
69
+ # A list of types that this type can inherit coercion behavior
70
+ # from. For example, a collection can be coerced into an
71
+ # array or a set.
74
72
  #
75
- # @param other [Object]
76
- # @return [Boolean]
77
- def self.eql?(other)
78
- if anonymous?
79
- superclass == other
80
- elsif other.respond_to?(:anonymous?) && other.anonymous?
81
- other.superclass.eql?(self)
82
- else
83
- super
84
- end
85
- end
86
-
87
- # (see .eql?)
88
- def self.==(other)
89
- eql?(other)
90
- end
91
-
92
- # Used by ruby's Hash, this determines the hash of the type. If
93
- # this is anonymous, it uses its supertype's hash.
94
- #
95
- # @see .eql?
96
- # @return [Numeric]
97
- def self.hash
98
- if anonymous?
99
- superclass.hash
100
- else
101
- super
102
- end
73
+ # @return [Array<Class>]
74
+ def self.inheritable
75
+ ancestors - Type.ancestors
103
76
  end
104
77
 
105
78
  # If this class is anonymous. This is counting on the fact that
data/lib/mixture/types.rb CHANGED
@@ -80,8 +80,8 @@ module Mixture
80
80
  # @return [Mixture::Types::Type] The inferred type.
81
81
  def self.infer_type(object)
82
82
  case object
83
- when ::Array then Array[infer(object.first)]
84
- when ::Set then Set[infer(object.first)]
83
+ when ::Array then Array[object.first]
84
+ when ::Set then Set[object.first]
85
85
  else types.reverse.find { |type| type.matches?(object) }
86
86
  end
87
87
  end
@@ -5,5 +5,5 @@ module Mixture
5
5
  # The current version of Mixture.
6
6
  #
7
7
  # @return [String]
8
- VERSION = "0.3.1"
8
+ VERSION = "0.3.2"
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixture
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Rodi