From: Daniel Finnie Date: 2008-05-08T03:41:16+09:00 Subject: Re: get method in Array subclass: where's it defined? ------=_Part_3755_15578764.1210185675679 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi, * is the splat operator. It means that all of the arguments to the method will go in the args variable. None of the def [] part affects this. If you call [] with the arguments 1, 2, and 3, then args will be an array with the values 1, 2, and 3. If you call [] with the arguments 1 and 3, then args will be an array with the values 1 and 3. If you call [] with one argument, then args will be an array containing only that argument. If you call [] with no arguments, then args will be an empty array. This behavior is useful because you don't know how many arguments [] was called with. So, when you do args.length == 2, you make sure that the [] method was called with two arguments. When you do args[0].is_a? Integer, you make sure that the first argument given was an integer, and likewise with the 2nd args[1].is_a? integer. Conversely, when you do get(*args), you use the splat operator in reverse. Instead of taking arguments and putting them into an array, you take an array and put use its elements as arguments like so: def max(a, b) if a > b a else b end end max(2, 3) #=> 3 max(3, 2) #=> 3 an_array = [3, 2] max(an_array) #=> Error because you only gave one argument, the array max(*an_array) #=> 3 because the array was split into arguments. On another note (sorry if this confuses you), a more idomatic way to write args[0].is_a? Integer and args[1].is_a? Integer is this: args.all? {|arg| arg.is_a? Integer } Dan On 5/7/08, RichardOnRails wrote: > > On May 7, 4:06 am, Albert Schlef wrote: > > RichardOnRails wrote: > > > m = Matrix[ [10,20,30], [40,50,60], [70,80,90] ]; > > > puts m [0] [1].inspect # 20 > > > puts m [2] [0].inspect # 70 > > > puts m[1].inspect # [40, 50, 60] > > [...] > > > my adaptation of Daniel's suggestion, including sub- > > > classing, works with no definition of get anywhere. And the code runs > > > without any visible definition of get > > > > Your code "works with no definition of get anywhere" because it doesn't > > utilize this 'get'. When you do "puts m [0] [1]" you aren't triggering > > your 'get'. That's because "m [0] [1]" is the plain-vanila array > > indexing; it uses one-dimensional indexing. It's exactly like doing "row > > = m[0]; row[1]". Multi-dimentional array indexing means: "m[0,1]". and > > if you tried that you'd trigger the call to 'get', and since it's > > absence, Ruby would complain. > > > > Implementiong your 'get' is no big deal. For a start, replace that > > "get(*args)" with "self[args[0]][args[1]]". > > -- > > Posted viahttp://www.ruby-forum.com/. > > Hi Albert, > > As you obviously recognized that I was totally out at sea on this > thing. The instrumented version, which I added in my reply to Phroz, > confirms your assessment that "get" was never invoked. > > While I'm grateful for that revelation, I am ever more grateful for > your additional, thorough analysis of the situation. I will employ > them to good effect. > > What's really at the root of my problems with this thing is my > ignorance about the def [] * args. > > It appears that what's being defined is "args". I concluded this by > changing its name and drawing an "undefined local variable or method > `args'" error message for the next line. To me, that seems weird. It > looks like C or C++ with type info before the name of a variable being > defined. > > I can't find "def [] *" on the net. Can you shed any light on this? > > Best wishes, > Richard > > > > > > ------=_Part_3755_15578764.1210185675679--