mixture 0.3.1 → 0.3.2

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
  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