From: "David A. Black" Date: 2009-02-26T06:11:09+09:00 Subject: Re: Where is splat implemented? / How does it work? Hi -- Rick DeNatale wrote: > On Wed, Feb 25, 2009 at 9:37 AM, David A. Black wrote: > >> Hi -- >> >> Mischa Fierer wrote: >> >>> Hi -- >>> >>> After a good amount of digging, I'm still not sure how [*[1,2]] == >>> [1,2]. I understand what it does, but I want to know why. >>> >>> I had originally assumed it was a normal method (like + or -), but it >>> appears to be implemented at a deeper level. It looks like rubinius does >>> something with cast_array. Ruby 1.8 does to_ary and ruby 1.9 does >>> to_splat. Where does this happen? to_ary says that it just returns self, >>> so how does self get exploded? >>> >>> Short of reading eval.c, does anyone have any pointers? >>> >> It ties itself to to_a: >> >>>> obj = Object.new >> => # >>>> def obj.to_a; [1,2,3]; end >> => nil >>>> a = *obj >> => [1, 2, 3] >> >> That code works the same in 1.8 and 1.9.1. There may be some classes where >> it's optimized away so that you can't override it even by defining to_a. I'm >> not sure. >> > > I'm pretty sure that implicit conversions to array use to_ary, not to_a. > This is the way it works in Ruby 1.8, and after an experimental period in > 1.9 with to_splat, it appears to have gone back to using to_ary. Grepping > the Ruby 1.9.1 source code for to_splat shows no hits. to_ary doesn't seem to be involved in 1.9.1. If you swap to_a for to_ary in my example it comes out the same in 1.8.6, but in 1.9.1 it doesn't: >> obj = Object.new => # >> def obj.to_ary; [1,2,3]; end => nil >> a = *obj => [#] David -- David A. Black / Ruby Power and Light, LLC Ruby/Rails consulting & training: http://www.rubypal.com Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2) Ruby Training Atlanta! April 1-3, http://www.entp.com/training/atlanta09