What's the difference between to_a and to_ary?
Asked Answered
D

4

59

What's the difference between to_a and to_ary?

Deadman answered 27/2, 2012 at 15:17 Comment(0)
W
61

to_ary is used for implicit conversions, while to_a is used for explict conversions.

For example:

class Coordinates
  attr_accessor :x, :y

  def initialize(x, y); @x, @y = x, y end

  def to_a; puts 'to_a called'; [x, y] end

  def to_ary; puts 'to_ary called'; [x, y] end

  def to_s; "(#{x}, #{y})" end

  def inspect; "#<#{self.class.name} #{to_s}>" end
end

c = Coordinates.new 10, 20
# => #<Coordinates (10, 20)>

The splat operator (*) is a form of explicit conversion to array:

c2 = Coordinates.new *c
# to_a called
# => #<Coordinates (10, 20)>

On the other hand, parallel assignment is a form of implicit conversion to array:

x, y = c
# to_ary called
puts x
# 10
puts y
# 20

And so is capturing collection members in block arguments:

[c, c2].each { |(x, y)| puts "Coordinates: #{x}, #{y}" }
# to_ary called
# Coordinates: 10, 20
# to_ary called
# Coordinates: 10, 20

Examples tested on ruby-1.9.3-p0.

This pattern seems to be used all over the Ruby language, as evidenced by method pairs like to_s and to_str, to_i and to_int and possibly more.

References:

Wattle answered 27/2, 2012 at 18:55 Comment(2)
Just noticed how to_ary provides way to pattern matching in blocks :)Airscrew
Avoid single-line methods. Although they are somewhat popular in the wild, there are a few peculiarities about their definition syntax that make their use undesirable. from rubystyle.guide/#no-single-line-methodsCircosta
A
24

to_ary allows an object to be treated as an array, whereas to_a actually tries to convert the parameter into an array.

to_ary can be useful for parallel assignment, whereas to_a is more suited for an actual conversion.

Acknowledge answered 27/2, 2012 at 15:33 Comment(0)
A
14

Quoted from gabew's web space:

Calling #to_a will convert the receiver to an Array, while #to_ary will not.

ruby-1.9.2-p290 :001 > class A < Array; end

ruby-1.9.2-p290 :004 > A[].to_a.class
 => Array

ruby-1.9.2-p290 :005 > A[].to_ary.class
 => A 
Askja answered 27/2, 2012 at 15:32 Comment(1)
Neither "converts" the receiver. "Converting the receiver" would somehow need to change the runtime type of the receiver (the object instance upon which the method is invoked). The reason why A[].to_ary.class returns A is because the base implementation of Array#to_ary returns self and A inherits Array. So the correct statement is "Calling #to_a will always return a new array representation of the receiver, while #to_ary could simply return the receiver if the receiver was already an array".Cordelia
S
1

to_a, when called on an object returns an array representation of obj

Examples

class Example
  def initialize
      @str = 'example'
  end
end

a = Example.new #=> #<Example:0x105a74af8 @str="example"
a.to_a #=> [#<Example:0x105a6a3a0 @str="example">]

Hash Example

h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  } 
h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]

An array can also be created by using the Array() method, provided by Kernel, which tries to call to_ary, then to_a on its argument. http://ruby-doc.org/core-2.0/Array.html#method-i-to_ary

so as far as I can see, the Array#to_ary src just returns the array that is passed in, as in

def to_ary
  return self
end

if I understand correctly, to_a is used for array conversion and makes its final return using to_ary. But this may not be true in future versions according to apidock

to_a Returns an array representation of obj. For objects of class Object and others that don’t explicitly override the method, the return value is an array containing self. However, this latter behavior will soon be obsolete. http://apidock.com/ruby/Object/to_a

Scrummage answered 17/5, 2013 at 20:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.