Hi --

On Mon, 24 Nov 2008, Brian Mitchell wrote:

> On Sun, Nov 23, 2008 at 04:00, David A. Black <dblack / rubypal.com> wrote:
>> Hi --
>>
>> In this code:
>>
>>>> def m(a,b="b",c="c",d); p [a,b,c,d]; end
>>
>> => nil
>>>>
>>>> m(1,2,3)
>>
>> [1, 2, "c", 3]
>> => [1, 2, "c", 3]
>>
>> I would expect [1, 3, "c", 2], because I would expect d (a required
>> argument) to be handled before b (an optional argument).
>>
>> I know it's almost unthinkable that one would use this method
>> signature, but I'd still like to understand the reasoning fully. I
>> thought the idea was: handle the required arguments first, but it
>> seems to be: move from left to right, looking ahead at every point to
>> see whether there are enough arguments left and, at that point, give
>> the right-hand required arguments priority. Is that right?
>
> Arguments should never be reordered (ignoring named argument
> possibilities). That would lead to even more insanity I think. It does
> mean that argument layout is a slightly complicated process now but
> knowing the arguments will keep an order should at least help
> guarantee that left and right arguments are satisfied properly.

They don't keep an absolute order, though. Watch what happens here:

irb(main):006:0> def m(a,b='b',c); p [a,b,c]; end
=> nil
irb(main):007:0> m(1,2)
[1, "b", 2]
=> [1, "b", 2]
irb(main):008:0> m(1,2,3)
[1, 2, 3]
=> [1, 2, 3]

The 2 argument moves from c to b in the binding, so that what looks
like the addition of an optional argument (3) actually changes two
bindings.

Of course one could simply not do this, and Koichi's example
(involving []=) showed a case where it's safer (because the rhs values
are quarantined from the others). But I think it's still got pitfalls.


David

-- 
Rails training from David A. Black and Ruby Power and Light:
   Intro to Ruby on Rails  January 12-15   Fort Lauderdale, FL
   Advancing with Rails    January 19-22   Fort Lauderdale, FL *
   * Co-taught with Patrick Ewing!
See http://www.rubypal.com for details and updates!