[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How does ruby handle overloading?

pongba

9/2/2007 12:49:00 PM

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.

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?

12 Answers

Sebastian Hungerecker

9/2/2007 1:26:00 PM

0

pongba wrote:
> 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);

def draw(arg)
if arg.is_a? Matrix
do_stuff
elsif arg.is_a? Graph
do_other_stuff
end
end

HTH,
Sebastian
--
NP: Dream Theater - Honor Thy Father
Jabber: sepp2k@jabber.org
ICQ: 205544826

dblack

9/2/2007 1:32:00 PM

0

Phrogz

9/2/2007 2:35:00 PM

0

On Sep 2, 6:48 am, pongba <pon...@gmail.com> wrote:
> This is a very general argument, what concerns me is ...
[snip]
> One might argue that [...] so the problem is moot.
> But then there's two more problems:
>
> 1. if we can't modify Matrix or Graph [...]
>
> 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?

What I hear you saying is:

There's a problem with what Matz describes, because...
OK, wait, that's not a problem.
But then there's this other problem:
Er, OK, that's not actually a problem either.
Can you please show me what the problem is?

I think you've reasoned it out for yourself: there isn't a problem.
Even if it were, the two other responses in this thread show you ways
you could work around it if you needed to (which you don't).

Robert Klemme

9/2/2007 4:26:00 PM

0

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 #<Matrix:0x7ff62e38>
=> nil
irb(main):013:0> Drawer.new.draw(Graph.new)
Drawing Graph #<Graph:0x7ff5fe54>
=> 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

Trans

9/2/2007 9:23:00 PM

0



On Sep 2, 5:50 am, pongba <pon...@gmail.com> 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.

There is a very good reading for support overloading, regardless. By
separating code based on interface it is much easier to override a
method. Without that one usually has to consider all the possible
interfaces in every override --even though one may only be interested
in a single one. OTOH, the downside of overriding is interface
collision --if more than one interface match, which method gets the
call? So it's actually easier to manage without it. And one can easily
work around the interface limitation by defining separate methods for
each case and having the main method as a simple dispatcher.

T.


pongba

9/3/2007 1:29:00 AM

0

On Sep 2, 9:25 pm, Sebastian Hungerecker <sep...@googlemail.com>
wrote:
> pongba wrote:
> > 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);
>
> def draw(arg)
> if arg.is_a? Matrix
> do_stuff
> elsif arg.is_a? Graph
> do_other_stuff
> end
> end
>
> HTH,
> Sebastian
> --
> NP: Dream Theater - Honor Thy Father
> Jabber: sep...@jabber.org
> ICQ: 205544826

But isn't type-switch generally believed to be a bad thing?

pongba

9/3/2007 1:32:00 AM

0

On Sep 2, 10:34 pm, Phrogz <phr...@mac.com> wrote:
> On Sep 2, 6:48 am, pongba <pon...@gmail.com> wrote:
>
> > This is a very general argument, what concerns me is ...
> [snip]
> > One might argue that [...] so the problem is moot.
> > But then there's two more problems:
>
> > 1. if we can't modify Matrix or Graph [...]
>
> > 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?
>
> What I hear you saying is:
>
> There's a problem with what Matz describes, because...
> OK, wait, that's not a problem.
> But then there's this other problem:
> Er, OK, that's not actually a problem either.
> Can you please show me what the problem is?
>
> I think you've reasoned it out for yourself: there isn't a problem.
> Even if it were, the two other responses in this thread show you ways
> you could work around it if you needed to (which you don't).

lol
Basically you're right.
What I wanted was an example that can only be solved with overloading,
but then there's the ultimate type-switch trick, so.. :P

pongba

9/3/2007 1:36:00 AM

0

On Sep 3, 12:26 am, Robert Klemme <shortcut...@googlemail.com> 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 #<Matrix:0x7ff62e38>
> => nil
> irb(main):013:0> Drawer.new.draw(Graph.new)
> Drawing Graph #<Graph:0x7ff5fe54>
> => 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.

dblack

9/3/2007 2:23:00 AM

0

pongba

9/3/2007 5:42:00 AM

0

On Sep 3, 10:23 am, dbl...@wobblini.net wrote:
> Hi --
>
>
>
> On Mon, 3 Sep 2007, pongba wrote:
> > On Sep 2, 9:25 pm, Sebastian Hungerecker <sep...@googlemail.com>
> > wrote:
> >> pongba wrote:
> >>> 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);
>
> >> def draw(arg)
> >> if arg.is_a? Matrix
> >> do_stuff
> >> elsif arg.is_a? Graph
> >> do_other_stuff
> >> end
> >> end
>
> >> HTH,
> >> Sebastian
> >> --
> >> NP: Dream Theater - Honor Thy Father
> >> Jabber: sep...@jabber.org
> >> ICQ: 205544826
>
> > But isn't type-switch generally believed to be a bad thing?
>
> It's actually class-switch (type and class aren't the same in Ruby),
> and it's an expedient that can be useful in some situations but tends
> to interfere with "thinking in Ruby", so to speak. Ruby generally is
> more about objects and their capabilities, and less about which
> classes happened to spawn them.
>
> David
>
> --
> * Books:
> RAILS ROUTING (new!http://www.awprofessional.com/title/...)
> RUBY FOR RAILS (http://www.manning...)
> * Ruby/Rails training
> & consulting: Ruby Power and Light, LLC (http://www.r...)

Thanks, David. That helps :-)