Why is overloading invalid in ruby

I don't understand why when I try to overload I get an error. Can I
overload somehow?

#!/usr/bin/env ruby

class Summer
  def sum(x)
    return x + 2
  end

  def sum(x,y)
    return x + y
  end

  def sum(x,y,z)
    return x + y + z
  end
end

s = Summer.new
puts s.sum(3)

ERROR:
ArgumentError: wrong number of arguments (1 for 3)

method sum in summer.rb at line 18
at top level in summer.rb at line 18

Ted

···

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

method with that name, it replaces it. So your class is left with only one
method, the one with 3 arguments. The first 2 get destroyed. The more
ruby-esque way to do this is to use optional parameters. Here's one simple
solution:

def sum(x,y=0,z=0)
  return x + y + z
end

···

On Thu, Jan 27, 2011 at 2:22 PM, Ted Flethuseo <flethuseo@gmail.com> wrote:

I don't understand why when I try to overload I get an error. Can I
overload somehow?

#!/usr/bin/env ruby

class Summer
def sum(x)
   return x + 2
end

def sum(x,y)
   return x + y
end

def sum(x,y,z)
   return x + y + z
end
end

s = Summer.new
puts s.sum(3)

ERROR:
ArgumentError: wrong number of arguments (1 for 3)

method sum in summer.rb at line 18
at top level in summer.rb at line 18

Ted

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

The problem is that when you define a method in a class that already has a

Ruby does not support method overloading. Searching the list archives
should turn up plenty of explanations.

Ben

···

On Thu, Jan 27, 2011 at 11:22 AM, Ted Flethuseo <flethuseo@gmail.com> wrote:

I don't understand why when I try to overload I get an error. Can I
overload somehow?

Ruby doesn't support method overloading. What your code does is giving three
definition of the sum method, with each definition overwriting the previous
one. This means that the first two definitions have no effect, since they're
overwritten by the third. At the end of your code, the sum method is defined
to take three arguments, so you obviously get an error when you try to call it
with only one argument.

You can achieve the same result giving some of the arguments default values:

class Summer

  def sum x, y = 2, z = 0
    x + y + z
  end

end

Now the sum method can be called with one, with two or with three arguments.
In the first case, y will be 2 and z will be three, so the result will be
computed as

x + 2 + 0

which is what you wanted. If it's called with two arguments, x and y will be
given the values passed as argument and z will be 0.

Another approach is to give sum a variable number of arguments, like this:

def sum x, *args
  args << 2 if args.empty?
  res = x
  args.each{|i| res += i}
  res
end

The * in front of args in the method definition tells ruby that args is
special: it stands in place of any number of arguments, from 0 upwards. When
the method is called, the first argument is assigned to x. Any other argument
(if any) is put in an array which is assigned to the variable args. In
particular, if sum is called with only one argument, args will be empty, so we
insert the value 2 in it (by the way, you could use Array#inject here, which
is much more elegant than what I wrote).

I hope this helps

Stefano

···

On Friday 28 January 2011 04:22:47 Ted Flethuseo wrote:

I don't understand why when I try to overload I get an error. Can I
overload somehow?

#!/usr/bin/env ruby

class Summer
  def sum(x)
    return x + 2
  end

  def sum(x,y)
    return x + y
  end

  def sum(x,y,z)
    return x + y + z
  end
end

s = Summer.new
puts s.sum(3)

ERROR:
ArgumentError: wrong number of arguments (1 for 3)

method sum in summer.rb at line 18
at top level in summer.rb at line 18

Ted

I guess the answer to your question is "Because you don't need to"

Overloading refers to two quite distinct situations. One is where you
want to involve parameters of different classes. You might want to add
two numbers or a number and a string. Ruby doesn't have anything like
the problem with that compared to more typed languages. The Ruby term is
"Duck Typing" which means Ruby will let you supply miscellaneous objects
and then see if they work in the context.

The second meaning - the one you demonstrated - is different numbers of
parameters. As other have pointed out, you can supply different numbers
of parameters to the same methods as long as you tell Ruby this might
happen and tell it how to deal with all the possibilties - with certain
constraints.

The problem is your example is pretty meaningless. You would be unlikely
to want to write a different method for each sum length.

Think of a more realistic scenario and then see if Ruby doesn't deal
with it.

(In the meantime, notice you really don't need to wrap your code in the
class Summer. I don't think it adds anything.)

(Oh dear, I shouldn't have said that...)

···

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

Ah that's too bad... I knew I could put some default values for x and y
and z.. getting the same effect sort of...

but this isn't a solution if the methods that I want to "overload" (I
call it
overload, not sure what the proper term should be) are
completely different, and are not differentiated simply by different
values.

Thank you for your reply though.

Ted

···

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

Ruby methods don't really have signatures, so overloading would be quite
difficult.

Disregarding your first sum, which adds 2, for some unknown reason, I would
write the method like this:

def sum(*numbers)
  sum = 0
  numbers.each { |number| sum += number }
  sum
end

Okay, I would probably actually write it like this, which is the same thing,
but less accessible to people who haven't encountered inject or reduce
before.

def sum(*numbers)
  numbers.inject { |sum,number| sum + number }
end

It could then be called with any number of arguments and types

sum 1 # => 1
sum 1 , 2 # => 3
sum 5 , 9 , 10 # => 24
sum 8 , 8 , 16 , 32 # => 64
sum 1.5 , 2.3 # => 3.8

In fact, it is flexible enough to take non-numeric types, though you
probably wouldn't ever use such a thing.

sum 'a' , 'b' # => "ab"
sum [1,2] , [3,4] # => [1, 2, 3, 4]

···

On Thu, Jan 27, 2011 at 1:22 PM, Ted Flethuseo <flethuseo@gmail.com> wrote:

I don't understand why when I try to overload I get an error. Can I
overload somehow?

#!/usr/bin/env ruby

class Summer
def sum(x)
   return x + 2
end

def sum(x,y)
   return x + y
end

def sum(x,y,z)
   return x + y + z
end
end

s = Summer.new
puts s.sum(3)

ERROR:
ArgumentError: wrong number of arguments (1 for 3)

method sum in summer.rb at line 18
at top level in summer.rb at line 18

Ted

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

Just to clarify what I was proposing (I am prepared to be corrected by
the experts here) - when you specify parameters to a Ruby method, Ruby
passes in variables. In Ruby, variables are references ie pointers to an
object. They of themselves are all the same data type. You can pass in
references to any object type. Ruby doesn't check the type of object
being referred to. One reason is at no point have you indicated what
type Ruby should expect.

At run time, inside the method body, Ruby will attempt to pass the
method name to the object referred to by your parameter. Only at that
point do we need things to match up.

The next step in the story is that = is a special case. It says make the
variable on the left hand side point to the object on the right hand
side. All other similar looking operators are actually methods on an
object. Ruby simply sends the message to the object concerned and sees
what happens.

In this scenario you can see how Ruby can deal with varying types (the
overloading gets shifted to the object being called - n possible object
types gives you n possible overloads.

However there's no corresponding way around the number (and order) of
parameters without the less elegant solutions discussed above.

Nobody sems to complain, so I suggest you don't worry about it. It's
unlikely to cramp your style.

···

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

I don't understand why when I try to overload I get an error. Can I
overload somehow?

Hi Ted,

sorry no overloading in ruby. overloading gives fixed/absolute power
to compiler/interpreter. ruby is dynamic, everything can be changed at
runtime, anytime. second, ruby is oo, ojbect first progg,
polymorph-based ie.

def sum(x)
return x + 2

      ^^
lose the return, ruby does not need it here

as others have mentioned, you can use starred args and default params
to mimic overloading. if that does not fit your taste, you can use
named params or hash (it fits mine :slight_smile:

the advantage of named params over static signature/position-based
param is that you have more control of your method since it is really
*the* params (wc are objects by themselves) that do the playing, not
the positioning (again, emphasizing o-o-ness). ergo, you have better
control and you can test/debug the methods a lot better.

now if that still does not suit your taste, you can do polymorphism,
wc of course comes natural in o-o langgs.

anyway, the ff code shows how to scheme thru named parameters way,

eg,

class Summer
  def sum(opt={:none=>"none entered :)"})
    case opt.keys.sort
      when [:none]
        opt[:none]
      when [:x]
        sumx opt[:x]
      when [:x, :y]
        sumxy opt[:x], opt[:y]
      when [:x, :y, :z]
        # you can place more conditions here
        sumxyz opt[:x], opt[:y], opt[:z]
      when [:a, :x, :y, :z]
        sumxyz_xa opt[:x], opt[:y], opt[:z], opt[:a]
      else
         # you can place other conditions and methods here, do anything
    end
  end

  private

  def sumx x
    x + 2
  end

  def sumxy x,y
    x + y
  end

  def sumxyz x,y,z
    x + y + z
  end

  def sumxyz_xa x,y,z,a
    sumxyz(x,y,z) ** a
  end
end
#=> nil

s = Summer.new
#=> #<Summer:0x918e350>
puts s.sum()
none entered :slight_smile:
#=> nil
puts s.sum(x:3)
5
#=> nil
# note also that the params have been disarranged to show flex
puts s.sum(x:3,y:4)
7
#=> nil
puts s.sum(z:5,x:3,y:4)
12
#=> nil
# this last sample call previous method and raises that to power :a
puts s.sum(y:4,a:6,x:3,z:5)
2985984
#=> nil

best regard -botp

···

On Fri, Jan 28, 2011 at 3:22 AM, Ted Flethuseo <flethuseo@gmail.com> wrote:

http://rubyworks.github.com/platypus/

So far I don't believe I've heard anyone make the obvious case against method overloading -- that unless done very carefully indeed, it makes the code much, much more difficult to read. One method does one job is the sane way to go, thanks.

Or, indeed, the practical case - at the very heart of Ruby is the idea of duck typing. Duck typing rules out method overloading, because parameters would have to have set types before you could have a signature. Presumably no-one is suggesting that we should have fixed typing in Ruby?

If they are so completely different, maybe the name of the method
should be different.
Can you share a bit more so we can give some recommendations?

Jesus.

···

On Thu, Jan 27, 2011 at 9:55 PM, Ted Flethuseo <flethuseo@gmail.com> wrote:

Ah that's too bad... I knew I could put some default values for x and y
and z.. getting the same effect sort of...

but this isn't a solution if the methods that I want to "overload" (I
call it
overload, not sure what the proper term should be) are
completely different, and are not differentiated simply by different
values.

If they're not differentiated by different values, how were you expecting
overloading to work? If the problem is that you need the behavior to be
different, I think default values still work -- for example:

def sum_or_inverse a, b=nil
  if b.nil?
    -a
  else
    a+b
  end
end

But I don't really know what you were asking.
I agree with Jesús. We need more details.

···

On Thursday, January 27, 2011 02:55:24 pm Ted Flethuseo wrote:

Ah that's too bad... I knew I could put some default values for x and y
and z.. getting the same effect sort of...

but this isn't a solution if the methods that I want to "overload" (I
call it
overload, not sure what the proper term should be) are
completely different, and are not differentiated simply by different
values.

For example the recent thread

http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/377008?376902-377590

and especially

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/377075

Cheers

robert

···

On Thu, Jan 27, 2011 at 8:48 PM, Ben Bleything <ben@bleything.net> wrote:

On Thu, Jan 27, 2011 at 11:22 AM, Ted Flethuseo <flethuseo@gmail.com> wrote:

I don't understand why when I try to overload I get an error. Can I
overload somehow?

Ruby does not support method overloading. Searching the list archives
should turn up plenty of explanations.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

So far I don't believe I've heard anyone make the obvious case against method overloading -- that unless done very carefully indeed, it makes the code much, much more difficult to read. One method does one job is the sane way to go, thanks.

I had tried to make the point here:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/377075

Or, indeed, the practical case - at the very heart of Ruby is the idea of duck typing. Duck typing rules out method overloading, because parameters would have to have set types before you could have a signature. Presumably no-one is suggesting that we should have fixed typing in Ruby?

Erm, actually there _are_ people who believe typing should change in
Ruby to support static typing features. There does not seem to be
much support for this in the community though. Obviously ducks feel
more at home in our community pond than metal skeletons. :slight_smile:

Kind regards

robert

···

On Mon, Jan 31, 2011 at 11:16 AM, Shadowfirebird <shadowfirebird@gmail.com> wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

I think the original poster provided an example of overloading based on the number of parameters but not their type.
Even restricting yourself to overloading by arity is a bit problematic in Ruby because the arity still has to be determined (in some cases) dynamically:

args = [1,2]
foo(*args) # two arguments
args << 3
foo(*args) # three arguments

Gary Wright

···

On Jan 31, 2011, at 5:16 AM, Shadowfirebird wrote:

Or, indeed, the practical case - at the very heart of Ruby is the idea of duck typing. Duck typing rules out method overloading, because parameters would have to have set types before you could have a signature. Presumably no-one is suggesting that we should have fixed typing in Ruby?

David Masover wrote in post #978005:

Ah that's too bad... I knew I could put some default values for x and y
and z.. getting the same effect sort of...

but this isn't a solution if the methods that I want to "overload" (I
call it
overload, not sure what the proper term should be) are
completely different, and are not differentiated simply by different
values.

If they're not differentiated by different values, how were you
expecting
overloading to work? If the problem is that you need the behavior to be
different, I think default values still work -- for example:

def sum_or_inverse a, b=nil
  if b.nil?
    -a
  else
    a+b
  end
end

But I don't really know what you were asking.
I agree with Jesús. We need more details.

Ok.. I didn't want to post so much code but you asked for it. I am
trying to read a file, with a number of different methods. The methods
allow you to interpret the file as an input and output matrices, input
only or both but with only a number of rows.

class CSVFile
  attr_accessor :inFile
  attr_accessor :file_data
  attr_accessor :in_data
  attr_accessor :out_data
  attr_reader :count

  def initialize(file)
    @inFile = file
    @file_data =
    @count = 0
    @in_data =
    @out_data =
  end

  def read_data
    if inFile.nil? == false
      @count = 0
      File.foreach(inFile) do |line|
        arr = line.chomp.split(',')
        float_array = arr.map { |x| x.to_f }
        file_data.push(float_array)
        @count = @count + 1
      end
    end
    return file_data
  end

  def read_data(num_in, num_out)
    if inFile.nil? == false
      @count = 0
      File.foreach(inFile) do |line|
        arr = line.chomp.split(',')
        float_array = arr.map { |x| x.to_f }
        arr_in =
        arr_out =
        for i in 0...num_in
          arr_in << float_array[i]
        end

        in_data.push(arr_in)
        for j in num_in...(num_in+num_out)
          arr_out << float_array[j]
        end
        out_data.push(arr_out)
        @count = @count + 1
      end
    end
    return file_data
  end

  def read_data(num_in, num_out, num_lines)
    if inFile.nil? == false
      @count = 0
      File.foreach(inFile) do |line|
        if @count >= num_lines
          break;
        end

        arr = line.chomp.split(',')
        float_array = arr.map { |x| x.to_f }
        arr_in =
        arr_out =
        for i in 0...num_in
          arr_in << float_array[i]
        end

        in_data.push(arr_in)
        for j in num_in...(num_in+num_out)
          arr_out << float_array[j]
        end
        out_data.push(arr_out)
        @count = @count + 1
      end
    end
    return file_data
  end
end

···

On Thursday, January 27, 2011 02:55:24 pm Ted Flethuseo wrote:

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

FWIW, I'd love for Ruby to support operator overloading. JRuby
supports it in Java-based Ruby methods (like the core classes) by
splitting the arities up into different call paths. I hope to do the
same under the covers for "overloaded" optional args forms, so that
this:

def foo(a, b = 1, c = 2)

would compile to the equivalent of this overloaded form:

def foo(a) foo(a, 1, 2)
def foo(a, b) foo(a, b, 2)
def foo(a, b, c) ...

When you look at optional args that way it doesn't seem so odd to take
the next leap and say ruby should allow separate logic for those
different paths rather than simply chaining them. For example, it's
uncommon but sometimes you'll see this form:

def foo(a, b = (c = true; 1)) ...

'b' is an optional arg that, when set to its optional value (i.e.
nothing passed in), also sets c = true. So you can check c to see if
the value of b came from the optional value or not. Gross!

If instead you could actually overload, it would simply be two methods:

def foo(a); b = 2; <logic for one-arg call>
def foo(a, b); <logic for two-arg call>

The fact that people have to use tricks like b = (c = true; 2) make me
think there's an opportunity here.

And it would be even cooler if Ruby supported some form of type-driven
pattern matching, so you could have different method bodies for
different input types rather than checking them over and over again.
But that's a post for another day :slight_smile:

- Charlie

···

On Fri, Jan 28, 2011 at 3:17 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Thu, Jan 27, 2011 at 8:48 PM, Ben Bleything <ben@bleything.net> wrote:

Ruby does not support method overloading. Searching the list archives
should turn up plenty of explanations.

For example the recent thread

http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/377008?376902-377590

and especially

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/377075

Actually, arity of callsite is always calculated in Ruby to know if
you should throw an ArgumentError (3 for 0 specified sort of errors)
against the method you are calling. It seems like overloading based
on arity is not such a bad idea to me based on some of the common
arity parsing idioms people do by hand in the first few lines of their
methods. What implementing arity-based overloads would do is get rid
of most of this code we put at the top of methods and perform that
logic in the Ruby implementation itself (in MRI in C vs in Ruby).

Stylistically, I think the biggest issue is not realizing there are n
overloads and then implementing less than n overloads in an overridden
class.

-Tom

···

On Mon, Jan 31, 2011 at 9:00 AM, Gary Wright <gwtmp01@mac.com> wrote:

On Jan 31, 2011, at 5:16 AM, Shadowfirebird wrote:

Or, indeed, the practical case - at the very heart of Ruby is the idea of duck typing. Duck typing rules out method overloading, because parameters would have to have set types before you could have a signature. Presumably no-one is suggesting that we should have fixed typing in Ruby?

I think the original poster provided an example of overloading based on the number of parameters but not their type.
Even restricting yourself to overloading by arity is a bit problematic in Ruby because the arity still has to be determined (in some cases) dynamically:

args = [1,2]
foo(*args) # two arguments
args << 3
foo(*args) # three arguments

--
blog: http://blog.enebo.com twitter: tom_enebo
mail: tom.enebo@gmail.com

ok, you've defined the class, thanks.
pls also show how'd you call/use so we do not have to invent here.

best regards -botp

···

On Fri, Jan 28, 2011 at 10:52 AM, Ted Flethuseo <flethuseo@gmail.com> wrote:

Ok.. I didn't want to post so much code but you asked for it. I am
trying to read a file, with a number of different methods. The methods
allow you to interpret the file as an input and output matrices, input
only or both but with only a number of rows.