## Implicit Conversions¶ ↑

Some Ruby methods accept one or more objects that can be either:

- Of a given class, and so accepted as is.

- Implicitly convertible to that class, 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 Array-convertible object is an object that:

- Has instance method `to_ary`.

- The method accepts no arguments.

- The method returns an object `obj` for which `obj.kind_of?(Array)` returns `true`.

The examples in this section use method `Array#replace`, 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 Hash-convertible object is an object that:

- Has instance method `to_hash`.

- The method accepts no arguments.

- The method returns an object `obj` for which `obj.kind_of?(Hash)` returns `true`.

The examples in this section use method `Hash#merge`, 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 Integer-convertible object is an object that:

- Has instance method `to_int`.

- The method accepts no arguments.

- The method returns an object `obj` for which `obj.kind_of?(Integer)` returns `true`.

The examples in this section use method `Array.new`, 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 String-convertible object is an object that:

- Has instance method `to_str`.

- The method accepts no arguments.

- The method returns an object `obj` for which `obj.kind_of?(String)` returns `true`.

The examples in this section use method `String::new`, 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)