Why doesn't Ruby allow for overloaded methods within a class

(from a Java refugee)

All,

I've done quite a bit of googling and read a bunch of posts about this,
but I'm looking for a simple explanation of why Ruby doesn't support
method overloading within a class to allow methods with the same name
but different numbers of arguments. I understand that you can't do
method overloading with the same # of arguments since you don't know any
"types" of input parameters when you invoke a method.

But...it seems like you could allow it for different numbers of input
parameters.

Here's an example of what I mean:
class Foo
  def methname(x,y)
    ...
  end

  def methname(x, y, z)
    ...
  end
end

I'm comfortable with how to implement this using a method with varargs
and appropriate logic, and I'm aware of arguments that the methods
should probably be different in name if their set of input parameters
are of different size.

But it seems like this kind method overloading would be doable in Ruby.
Is it possible?
Is it not available because there's a feeling that it isn't needed?

Thanks,
Wes

···

--
Posted via http://www.ruby-forum.com/.

Wes Gamble wrote:

(from a Java refugee)

All,

I've done quite a bit of googling and read a bunch of posts about this,
but I'm looking for a simple explanation of why Ruby doesn't support
method overloading within a class to allow methods with the same name
but different numbers of arguments. I understand that you can't do
method overloading with the same # of arguments since you don't know any
"types" of input parameters when you invoke a method.

But...it seems like you could allow it for different numbers of input
parameters.

Here's an example of what I mean:
class Foo
  def methname(x,y)
    ...
  end

  def methname(x, y, z)
    ...
  end
end

I'm comfortable with how to implement this using a method with varargs
and appropriate logic, and I'm aware of arguments that the methods
should probably be different in name if their set of input parameters
are of different size.

But it seems like this kind method overloading would be doable in Ruby.
Is it possible?
Is it not available because there's a feeling that it isn't needed?

  Use default arguments

  def methname(x,y, z = false)
    if z
    else
  end

  If false is a valid value for z, you can try z = :special
  if z == :special

  Moreover, most of the time, quite a bit of code is shared from the
2-args version to the 3-args version. Actually, if that is not the case,
it is probably a sign that the functionality shouldn't be regrouped
under a unique name.

  Cheers,

  Vince

···

--
Vincent Fourmond, PhD student
http://vincent.fourmond.neuf.fr/

I'm comfortable with how to implement this using a method with varargs
and appropriate logic, and I'm aware of arguments that the methods
should probably be different in name if their set of input parameters
are of different size.

But it seems like this kind method overloading would be doable in Ruby.
Is it possible?

Theoretically, yes.

Is it not available because there's a feeling that it isn't needed?

My guess is that Matz's reasoning here is to keep it simple. Introducing this feature will make a lot things much more complicated - inside the interpreter as well as for the user. Just think of method dispatching and things like define_method and method_missing. And then there's of course the logic: what will happen here?

class Foo
   def bar(*a) end
   def bar() end
end

# which method to invoke?
Foo.new.bar()

Kind regards

  robert

···

On 12.01.2007 09:16, Wes Gamble wrote:

On Behalf Of Wes Gamble:
# Here's an example of what I mean:
# class Foo
# def methname(x,y)
# ...
# end

···

#
# def methname(x, y, z)
# ...
# end
# end
# ...
# But it seems like this kind method overloading would be
# doable in Ruby.
# Is it possible?

Hi Wes,

from my nuby experience, no.

what would you expect ruby to do if you have

  class A
    def a
    end
  end

  class A
    def a b
    end
  end

?

you'd want ruby to create two methods of same name "a" but w diff params, no? BUT, what if i really want to change method "a", and want it to receive 2 params among other things? "but what if i want to retain the old "a"? ", you might ask. No problem, you can give it a different name by alias-ing it, eg, old_a. It is easier for me to remember names than remember different params and their combinations/positioning thereof.

also, ruby allows this

  def a *b
  end

is that one or multi params?
(btw, you may not see the block param. it's magic)

:slight_smile:

ergo, ruby does method "dynamic reloading" and loads w whatever changes it carries w its load. it's just a term i learn from "the matrix" :slight_smile:

# Is it not available because there's a feeling that it isn't needed?

ruby is object oriented (not method oriented) eg, string.length, array.length, hash.length etc. Note, no change name there (only change in objects) and they may have diff params, too. One method name to remember, easy for my brain.

maybe you can provide an example where you need method overloading?

kind regards -botp

Wes Gamble wrote:

but I'm looking for a simple explanation of why Ruby doesn't support
method overloading within a class to allow methods with the same name
but different numbers of arguments. I understand that you can't do

You see, almost none of dynamic languages support this feature because
of real problems with detecting, which method to use.

class Foo
  def methodname(x, y)
  end

  def methodname(x, *args)
  end
end

Which to use in case of Foo.new.methodname(1,2) ?

···

--
Posted via http://www.ruby-forum.com/\.

I'm not completely sure about this, but what would you do about optional arguments?

Wes Gamble wrote, On 1/12/2007 2:16 AM:

···

(from a Java refugee)

All,

I've done quite a bit of googling and read a bunch of posts about this,
but I'm looking for a simple explanation of why Ruby doesn't support
method overloading within a class to allow methods with the same name
but different numbers of arguments. I understand that you can't do
method overloading with the same # of arguments since you don't know any
"types" of input parameters when you invoke a method.

But...it seems like you could allow it for different numbers of input
parameters.

Here's an example of what I mean:
class Foo
  def methname(x,y)
    ...
  end

  def methname(x, y, z)
    ...
  end
end

I'm comfortable with how to implement this using a method with varargs
and appropriate logic, and I'm aware of arguments that the methods
should probably be different in name if their set of input parameters
are of different size.

But it seems like this kind method overloading would be doable in Ruby.
Is it possible?
Is it not available because there's a feeling that it isn't needed?

Thanks,
Wes

Hi --

(from a Java refugee)

All,

I've done quite a bit of googling and read a bunch of posts about this,
but I'm looking for a simple explanation of why Ruby doesn't support
method overloading within a class to allow methods with the same name
but different numbers of arguments. I understand that you can't do
method overloading with the same # of arguments since you don't know any
"types" of input parameters when you invoke a method.

But...it seems like you could allow it for different numbers of input
parameters.

Here's an example of what I mean:
class Foo
def methname(x,y)
   ...
end

def methname(x, y, z)
   ...
end
end

I'm comfortable with how to implement this using a method with varargs
and appropriate logic, and I'm aware of arguments that the methods
should probably be different in name if their set of input parameters
are of different size.

But it seems like this kind method overloading would be doable in Ruby.
Is it possible?
Is it not available because there's a feeling that it isn't needed?

I've never extensively used any language that has this feature, but
it's always struck me as a bit strange, and very brittle. What if you
want two method behaviors, but both behaviors involve having the same
number of arguments? It's always seemed to me a bit like having
methods dispatch on what letter of the alphabet their parameters begin
with.

So... I guess my view is that Ruby has evolved beyond it, though there
may be some use for it that I'm just not seeing.

David

···

On Fri, 12 Jan 2007, Wes Gamble wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Wes Gamble wrote:

I've done quite a bit of googling and read a bunch of posts about this,
but I'm looking for a simple explanation of why Ruby doesn't support
method overloading within a class to allow methods with the same name
but different numbers of arguments.

In my mind, this makes sense in a statically-typed language. The
signature of the method is reasonably clear in that case. "If I pass an
array, do A; if I pass a Vector, do B; if I pass a number, do C; if I
pass an array and a number, do D."

It seems like a very floppy, weak signature to change behavior just on
the *number* of arguments. "If I pass one thing...uhm...well, I guess
it depends on what that one thing is internally, so I'll have to branch
inside. If I pass two things...it's different from one things, but
again, it depends on which two things are passed in." You'd end up
mixing your operation determination between automatic method choosing
and between code that you have to write anyhow inside the methods.

Max Lapshin wrote:

Wes Gamble wrote:

but I'm looking for a simple explanation of why Ruby doesn't support
method overloading within a class to allow methods with the same name
but different numbers of arguments. I understand that you can't do

You see, almost none of dynamic languages support this feature because
of real problems with detecting, which method to use.

class Foo
  def methodname(x, y)
  end

  def methodname(x, *args)
  end
end

Which to use in case of Foo.new.methodname(1,2) ?

Max,

Thanks, I hadn't considered that.

Wes

···

--
Posted via http://www.ruby-forum.com/\.

I've never extensively used any language that has this feature, but
it's always struck me as a bit strange, and very brittle. What if you
want two method behaviors, but both behaviors involve having the same
number of arguments? It's always seemed to me a bit like having
methods dispatch on what letter of the alphabet their parameters begin
with.

So... I guess my view is that Ruby has evolved beyond it, though there
may be some use for it that I'm just not seeing.

Actually, I would say that Ruby uses overloading far more than most
other languages. What does "overloading" actually mean? Basically it
means implementing more than one behaviour for the same language
element. You do that in Ruby perhaps even more than in most other
languages. In Ruby you even do it at run-time by extending classes,
replacing functions, etc.

Consider the top-level method "open". If you mixin the functionality
from the open-uri library, you are basically overloading that function
to behave differently according to the value of its arguments. Or
perhaps a better example is the 'puts' function. I don't know if it is
written in Ruby, but an implementation might look something like this:

def puts(arg)
  if arg.is_a? String then
    # write out the string
  elsif arg.is_a? Number
    s = arg.to_s
    # write out the string s
   else
    # etc. etc.
   end
end

This is basically overloading of a method. But it is implemented
entirely by the programmer with no help from the language. Now, in a
statically typed language such as Java, you cannot do the above because
the argument must specify a type. Thus, you have to do something like

void puts(String arg) {
  # write out the string
}

void puts(int arg) {
  # convert the int to a string and write it out
}

(Ignoring for a moment the fact that Java 1.5 introduced auto-boxing of
primitive types.)

Which is better? Which uses overloading more than the other? Neither of
them. But a language with static typing is often somewhat limited in
how much they can overload a function.

Getting back to the OP's question. What I believe he simply wants, is
some language construct that would assist him when overloading method
behaviour depending on the number of actual arguments received. That a
fair request in itself. Unfortunately, as others have pointed out, it
doesn't go too well with the fact that defining a method more than once
means overwriting the old definitions. However, I am sure some
meta-programming expert could come up with a function that would allow
us to write something like this:

overload do
  def methodName(arg)
    # code block A
  end
  def methodName(arg1, arg2)
    # code block B
  end
end

Basically this would be translated into something like:

def methodName1(arg)
  # code block A
end
def methodName2(arg1, arg2)
  # code block B
end
def methodName(arg1, arg2=nil)
  if arg2.nil? then
    methodName1(arg1)
  else
    methodName2(arg1, arg2)
  end
end

I think that might be very useful in some cases actually. I wonder if
it can be done.

Wes Gamble wrote:

Thanks, I hadn't considered that.

Wes

Think about this:

class Foo
  def methodname(Foo a)
    puts a.value
  end

  def methodname(String a)
    puts "bar: "+a
  end
end

class FooTest < Test::Unit::TestCase
  def test_methodname
    @mock_foo = "some mock string value"
    def @mock_foo.value
      self
    end
    @foo = Foo.new
    assert_equal "some mock string value", @foo.methodname(@mock_foo)
  end
end

Problems =)

···

--
Posted via http://www.ruby-forum.com/\.

It goes 100% against duck typing.

class Name < String
  # ...
end

def methodName(String a)
  # ...
end

Does methodName accept the Name class?

And what if you just had a NumericString class that implemented all of the String and Numeric methods, but wasn't a descendant of either class? Would methodName(String a) accept that class as input?

Dan

Max Lapshin wrote:

···

Wes Gamble wrote:

Thanks, I hadn't considered that.

Wes

Think about this:

class Foo
  def methodname(Foo a)
    puts a.value
  end

  def methodname(String a)
    puts "bar: "+a
  end
end

class FooTest < Test::Unit::TestCase
  def test_methodname
    @mock_foo = "some mock string value"
    def @mock_foo.value
      self
    end
    @foo = Foo.new
    assert_equal "some mock string value", @foo.methodname(@mock_foo)
  end
end

Problems =)