If you have a subclass X of Array, then doing X#to_a returns an array object, while doing X#to_ary returns an x object.
While I understand that to_a means “I can be changed into an array”, while to_ary means “I behave like an array”, I don’t understand why the former implements a change of class while the latter doesn’t.
Also, isn’t returning a subclass of Array sufficient for to_a, under the Liskov Substitution Principle?
Is “because that’s the way it’s defined to be” sufficient?
Probably not, so here we go into the rabbit hole.
Beyond the fact that the documentation definitively states that this is the way it is, the reasoning is perhaps only truly answerable by Matz, et al.
Digging around though it would seem that
to_aryis used when implicit type conversions occur. Its use for implicit conversions seems to be echoed in this feature request as well. In other words, if an object responds toto_ary, then it should be treated as anArray, and it is used in this way internally. Thusto_awould be for when you (explicitly) want anArrayand not some subclass.Yes, returning a subclass would still satisfy LSP (assuming the subclass does not decide to radically change the behavior of
Arraysuch that it wouldn’t be), but the principle only states that a subclass may be substituted for its base class, not that it needs to be. I’m not really sure that matter here anyway, though, since you’re callingto_ayour explicitly asking for a different object (to go along with the reasoning about implicit conversions above) and thus you’re saying you don’t want a substitute object type.