From: Robert Klemme Date: 2007-09-03T14:50:04+09:00 Subject: Re: How does ruby handle overloading? On 03.09.2007 03:36, pongba wrote: > On Sep 3, 12:26 am, Robert Klemme wrote: >> On 02.09.2007 14:48, pongba wrote: >> >> >> >>> Matz once replied on Cedric's blog that >>> I am not against "method overloading", but it very easily leads to >>> optional static typing in the language, which changes the language >>> very drastically, since you need to specify "type" to overload >>> arguments. Without well-thought design, it can "destroy" the language >>> and its culture. I have not yet got that well-thought design of method >>> overloading. >>> This is a very general argument, what concerns me is that if, for >>> instance, we have Matrix and Graph, and we'd like to be able to draw >>> both of them (the two 'draw's would have the same semantic but >>> different implementation logic), how 're we going to be able to >>> overload draw on Matrix and Graph like what we do in C++ or Java: >>> void draw(Matrix); >>> void draw(Graph); >>> One might argue that 'draw' should actually be a member function of >>> Matrix and Graph so the problem is moot. But then there's two more >>> problems: >>> 1. if we can't modify Matrix or Graph, and writing a non-member 'draw' >>> is the only thing we can do to extend the interface of them, and we >>> actually can write 'draw' in terms of the public interface of Matrix >>> and Graph. >> Somehow I miss something in this sentence. You write "if..." but I do >> not see any "then". So what exactly are you trying to say / ask here? >> >> You can usually change classes. Also, there are numerous ways to >> implement dispatching on argument types, for example this one: >> >> class Drawer >> @draw = Hash.new(lambda {|x| raise "Cannot draw #{x.inspect}"}). >> merge(Matrix => lambda {|x| puts "Drawing Matrix #{x.inspect}"}, >> Graph => lambda {|x| puts "Drawing Graph #{x.inspect}"}) >> >> def draw(obj) >> self.class.instance_eval {@draw}[obj.class][obj] >> end >> end >> >> irb(main):012:0> Drawer.new.draw(Matrix.new) >> Drawing Matrix # >> => nil >> irb(main):013:0> Drawer.new.draw(Graph.new) >> Drawing Graph # >> => nil >> irb(main):014:0> Drawer.new.draw("foo") >> RuntimeError: Cannot draw "foo" >> from (irb):4 >> from (irb):9:in `[]' >> from (irb):9:in `draw' >> from (irb):14 >> from :0 >> irb(main):015:0> >> >> There are others, you can find some of them in the Ruby Garden Wiki >> (which seems to be unavailable ATM). >> >>> 2. if '1' doesn't matter (because in ruby we actually can add new >>> methods to an existing class), then can you please give another more >>> qualified example? >> Example for what? >> >> Kind regards >> >> robert > > Sorry, I meant 'what if' :-) > There're lots of ways to implement them, among which the more > automatic one is the StrongType module. But they all rely on explicit > dynamic type-switch, which isn't as clear as the "traditional" > overloading mechanism(i.e. draw(Matrix); draw(Graph); ). > I don't whether there're other problem related to this approach since > I'm a ruby-newbie. If you read Matz's statement (which you quoted) again you'll find the reason why there is not that kind of overloading you are looking for. :-) robert