hamstergem / hamster

Efficient, Immutable, Thread-Safe Collection classes for Ruby
Other
1.89k stars 94 forks source link

Vector#to_ary should return self #186

Closed xaviershay closed 9 years ago

xaviershay commented 9 years ago

to_ary is used for implicit conversion only, and as such doesn't need to convert to a Ruby array.

irb(main):060:0> Hamster::Vector[].to_ary.class
=> Array

I can't find canonical documentation for this, but http://stackoverflow.com/questions/9467395/whats-the-difference-between-to-a-and-to-ary-in-activerecord provides a selection of links that seems to support this behaviour.

alexdowad commented 9 years ago

to_ary is used for implicit conversion... to a Ruby array. In some cases, when the Ruby interpreter wants an Array, but finds something else, it will call #to_ary on it and expect to get an Array back. So #to_ary needs to return an Array.

If there's something I'm missing, feel free to re-open this issue.

xaviershay commented 9 years ago

hrmm ok, let me poke around. My understanding was if it actually needed an Array, rather than just something that looked like one, it would use #to_a.

xaviershay commented 9 years ago

... and the reason I brought this up is I think we want this to correctly implement https://github.com/hamstergem/hamster/issues/185 (and likely other methods) without having to pay the cost of converting sub-Vectors into arrays.

alexdowad commented 9 years ago

I see. That performance issue is a concern -- we want everything to be as fast as is practicable. But breaking #to_ary to make #transpose faster is not an option.

Regarding "implicit" conversion to Array, that just means that the Ruby interpreter internally converts an object to an Array. To see where and why this is done, consult the MRI code. (If you've never dug into it before, it's not that bad.)

xaviershay commented 9 years ago

I have convinced myself that you are correct. Ruby does do an explicit type check.

class MyVector
  def to_ary
    self
  end
end

Array.new(MyVector.new)
test.rb:25:in `initialize': can't convert MyVector to Array (MyVector#to_ary gives MyVector) (TypeError)