1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
== Implicit Conversions
Some Ruby methods accept one or more objects
that can be either:
* <i>Of a given class</i>, and so accepted as is.
* <i>Implicitly convertible to that class</i>, in which case
the called method converts the object.
For each of the relevant classes, the conversion is done by calling
a specific conversion method:
* Array: +to_ary+
* Hash: +to_hash+
* Integer: +to_int+
* String: +to_str+
=== Array-Convertible Objects
An <i>Array-convertible object</i> is an object that:
* Has instance method +to_ary+.
* The method accepts no arguments.
* The method returns an object +obj+ for which <tt>obj.kind_of?(Array)</tt> returns +true+.
The examples in this section use method <tt>Array#replace</tt>,
which accepts an Array-convertible argument.
This class is Array-convertible:
class ArrayConvertible
def to_ary
[:foo, 'bar', 2]
end
end
a = []
a.replace(ArrayConvertible.new) # => [:foo, "bar", 2]
This class is not Array-convertible (no +to_ary+ method):
class NotArrayConvertible; end
a = []
# Raises TypeError (no implicit conversion of NotArrayConvertible into Array)
a.replace(NotArrayConvertible.new)
This class is not Array-convertible (method +to_ary+ takes arguments):
class NotArrayConvertible
def to_ary(x)
[:foo, 'bar', 2]
end
end
a = []
# Raises ArgumentError (wrong number of arguments (given 0, expected 1))
a.replace(NotArrayConvertible.new)
This class is not Array-convertible (method +to_ary+ returns non-Array):
class NotArrayConvertible
def to_ary
:foo
end
end
a = []
# Raises TypeError (can't convert NotArrayConvertible to Array (NotArrayConvertible#to_ary gives Symbol))
a.replace(NotArrayConvertible.new)
=== Hash-Convertible Objects
A <i>Hash-convertible object</i> is an object that:
* Has instance method +to_hash+.
* The method accepts no arguments.
* The method returns an object +obj+ for which <tt>obj.kind_of?(Hash)</tt> returns +true+.
The examples in this section use method <tt>Hash#merge</tt>,
which accepts a Hash-convertible argument.
This class is Hash-convertible:
class HashConvertible
def to_hash
{foo: 0, bar: 1, baz: 2}
end
end
h = {}
h.merge(HashConvertible.new) # => {:foo=>0, :bar=>1, :baz=>2}
This class is not Hash-convertible (no +to_hash+ method):
class NotHashConvertible; end
h = {}
# Raises TypeError (no implicit conversion of NotHashConvertible into Hash)
h.merge(NotHashConvertible.new)
This class is not Hash-convertible (method +to_hash+ takes arguments):
class NotHashConvertible
def to_hash(x)
{foo: 0, bar: 1, baz: 2}
end
end
h = {}
# Raises ArgumentError (wrong number of arguments (given 0, expected 1))
h.merge(NotHashConvertible.new)
This class is not Hash-convertible (method +to_hash+ returns non-Hash):
class NotHashConvertible
def to_hash
:foo
end
end
h = {}
# Raises TypeError (can't convert NotHashConvertible to Hash (ToHashReturnsNonHash#to_hash gives Symbol))
h.merge(NotHashConvertible.new)
=== Integer-Convertible Objects
An <i>Integer-convertible object</i> is an object that:
* Has instance method +to_int+.
* The method accepts no arguments.
* The method returns an object +obj+ for which <tt>obj.kind_of?(Integer)</tt> returns +true+.
The examples in this section use method <tt>Array.new</tt>,
which accepts an Integer-convertible argument.
This user-defined class is Integer-convertible:
class IntegerConvertible
def to_int
3
end
end
a = Array.new(IntegerConvertible.new).size
a # => 3
This class is not Integer-convertible (method +to_int+ takes arguments):
class NotIntegerConvertible
def to_int(x)
3
end
end
# Raises ArgumentError (wrong number of arguments (given 0, expected 1))
Array.new(NotIntegerConvertible.new)
This class is not Integer-convertible (method +to_int+ returns non-Integer):
class NotIntegerConvertible
def to_int
:foo
end
end
# Raises TypeError (can't convert NotIntegerConvertible to Integer (NotIntegerConvertible#to_int gives Symbol))
Array.new(NotIntegerConvertible.new)
=== String-Convertible Objects
A <i>String-convertible object</i> is an object that:
* Has instance method +to_str+.
* The method accepts no arguments.
* The method returns an object +obj+ for which <tt>obj.kind_of?(String)</tt> returns +true+.
The examples in this section use method <tt>String::new</tt>,
which accepts a String-convertible argument.
This class is String-convertible:
class StringConvertible
def to_str
'foo'
end
end
String.new(StringConvertible.new) # => "foo"
This class is not String-convertible (no +to_str+ method):
class NotStringConvertible; end
# Raises TypeError (no implicit conversion of NotStringConvertible into String)
String.new(NotStringConvertible.new)
This class is not String-convertible (method +to_str+ takes arguments):
class NotStringConvertible
def to_str(x)
'foo'
end
end
# Raises ArgumentError (wrong number of arguments (given 0, expected 1))
String.new(NotStringConvertible.new)
This class is not String-convertible (method +to_str+ returns non-String):
class NotStringConvertible
def to_str
:foo
end
end
# Raises TypeError (can't convert NotStringConvertible to String (NotStringConvertible#to_str gives Symbol))
String.new(NotStringConvertible.new)
|