How does ruby handle overloading?

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?

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

Hi –

On Sun, 2 Sep 2007, pongba wrote:

instance, we have Matrix and Graph, and we’d like to be able to draw

  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?

I am a great believer in ‘extend’.

module MatrixEnhancements
def draw

end
end
m = Matrix.new.extend(MatrixEnhancements)

This lets you endow specific objects with what they need, and you
don’t have to change classes globally. It is, in my opinion, a much
under-utilized technique.

David

On Sep 2, 6:48 am, pongba [email protected] 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).

On 02.09.2007 14:48, pongba wrote:

instance, we have Matrix and Graph, and we’d like to be able to draw

  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:indraw’
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).

  1. 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

On Sep 2, 10:34 pm, Phrogz [email protected] wrote:

methods to an existing class), then can you please give another more
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… :stuck_out_tongue:

On Sep 2, 9:25 pm, Sebastian H. [email protected]
wrote:

def draw(arg)
NP: Dream Theater - Honor Thy Father
Jabber: [email protected]
ICQ: 205544826

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

On Sep 3, 12:26 am, Robert K. [email protected] wrote:

and its culture. I have not yet got that well-thought design of method

not see any “then”. So what exactly are you trying to say / ask here?
self.class.instance_eval {@draw}[obj.class][obj]
RuntimeError: Cannot draw “foo”

  1. 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’ :slight_smile:
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.

On Sep 2, 5:50 am, pongba [email protected] wrote:

instance, we have Matrix and Graph, and we’d like to be able to draw

  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.

Hi –

On Mon, 3 Sep 2007, pongba wrote:

void draw(Graph);
Sebastian

NP: Dream Theater - Honor Thy Father
Jabber: [email protected]
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

On 03.09.2007 03:36, pongba wrote:

and its culture. I have not yet got that well-thought design of method
problems:
class Drawer
Drawing Matrix #Matrix:0x7ff62e38
from :0
Kind regards

    robert

Sorry, I meant ‘what if’ :slight_smile:
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.
:slight_smile:

robert

On Sep 3, 10:23 am, [email protected] wrote:

both of them (the two 'draw’s would have the same semantic but
do_other_stuff
But isn’t type-switch generally believed to be a bad thing?

Thanks, David. That helps :slight_smile:

On Sep 2, 5:50 am, pongba [email protected] 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.

Just FYI, I developed one a long time ago, based on Euphoria’s model.
Basically worked like this, You define a “type” as such:

type :foo, SomeClass, Modules, ..., :methods, ... do |v|
  # validation block ...
end

Such that type “foo” is a subclass of SomeClass and/or includes
Modules, and/or repsonds_to? :methods, and/or validates against the
given block.

You’d then use this type definition to validate:

def x(v)
foo!(v)

end

Of course, ideally then you could do:

def x(foo v)

end

Seems to me that’s about the best one could do with a Ruby overload
system. Question is, is it worth the overhead?

T.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs