From: "Jörg W Mittag" Date: 2011-02-01T02:36:21+09:00 Subject: Re: why is overloading invalid in ruby. Charles Oliver Nutter wrote: > On Sat, Jan 29, 2011 at 12:37 AM, Eric Christopherson > wrote: >> Specifically, MacRuby has an extension to the usual hash parameters >> that seems pretty complicated to me, but allows it to interact fairly >> painlessly with Objective-C*. It basically allows you to define a >> method with named parameters. It's bewildering because a method >> invocation like "person.setFirstName('Gloria', { :lastName=>'Alvarez' >> })" actually calls a *different* method from >> "person.setFirstName('Gloria', lastName: 'Alvarez')" (the former is >> the regular Ruby hash argument type; the latter uses the >> MacRuby-specific keyed arguments. If no keyed-argument version of a >> method exists, it will just translate it into a hash-argument form.) > Laurent can correct me if I'm wrong, but I don't think ObjC's syntax > qualifies as true named arguments. Yes. Objective-C inherits its syntax from Smalltalk, which just has plain old boring standard positional arguments like every other language, like C, like Ruby minus optional and splat arguments. The only peculiarity is that the arguments get written between the subroutine name instead of at the end. So, if you have a method named foo:bar:baz: which takes three arguments, the way you would call it in pretty much every other language is foo:bar:baz:(1, 2, 3) whereas in Smalltalk it's foo: 1 bar: 2 baz: 3 This allows you to achieve some nice readability with clever method naming, i.e. instead of dictionary.add(1, 2) # which one's the key and which is the value? you get dictionary at: 1 put: 2. But fundamentally, these are still positional arguments. I could, for example, do this in Ruby: dictionary.at_first_put_second(1, 2) > In MacRuby/ObjC, a method call like > > foo(bar:1, baz:2) > > Is just a way of saying something like > > foo_with_bar_with_baz(1, 2) More precisely, your example (roughly) translates to the following snippet of Smalltalk: temp := Dictionary new. temp at: #bar put: 1. 'No dictionary literals in Smalltalk' foo: temp baz: 2. i.e. in Ruby: send(:'foo:baz:', { :bar => 1 }, 2) A better example would be foo(1, bar: 2, baz: 3) which translates to foo: 1 bar: 2 baz: 3. or send(:'foo:bar:baz:', 1, 2, 3) > The method name and the argument names actually resolve to different > method bodies internally. In addition, the order is absolutely > crucial. The following two calls are not the same and will not end up > in the same target method: > > foo(bar: 1, baz: 2) > foo(baz: 2, bar: 1) Correct. The only reason why you can say condition ifTrue: [doThis] ifFalse: [doThat]. condition ifFalse: [doThat] ifTrue: [doThis]. condition ifTrue: [doThis]; ifFalse: [doThat]. is because TrueClass and FalseClass define four methods ifTrue:ifFalse: ifFalse:ifTrue: ifTrue: ifFalse: With named arguments (and optional arguments), you would have just one method: def if(then=->{}, else=->{}) jwm