How to realize method/function overloading in Ruby?

S

Shiwei Zhang

I think Function Overloading in C++ is very meaningful. And currently
the case for me is: How I can make use of method/function overloading
in Ruby?
Besides you might tell me Ruby is designed to exclude method
overloading, can you tell me sth more for the Overloading purpose?
 
G

gwtmp01

I think Function Overloading in C++ is very meaningful. And
currently the case for me is: How I can make use of method/
function overloading in Ruby?
Besides you might tell me Ruby is designed to exclude method
overloading, can you tell me sth more for the Overloading purpose?

This is a common question. The short answer is that function
overloading is based on knowing the static types of the actual
arguments to a method and in Ruby the entire notion of 'static types
of the actual arguments' is pretty much non-existent.

The longer answer is that for Ruby to provide some sort of
overloading a new syntax for method definition would be required and
then the method lookup algorithm would have to be updated. Warning:
pseudo code ahead.

def do_something( a as Array)
#...
end

def do_something( a as Hash)
#...
end

def do_something(a)
#...
end

do_something([1,2]) # as Array version
do_something({1,2}) # as Hash version
do_something(1) # unspecified version

This would really complicate the method dispatch mechanism as the
class of every argument would have to be examined *each* time any
method is called. I used literal arrays, hashes, and integers in the
example but in general they would
just be arbitrary expressions. In any case some sort of algorithm
would have to be run each time a method was called. This would
drastically increase method call overhead in Ruby.

This is a lot of work when the programmer can achieve the same goal
with the existing language quite concisely:

def do_something(a)
case a
when Array
# work with array
when Hash
# work with hash
else
# assume integer
end
end

Same effect, no language changes, and the algorithm is explicit and
flexible rather than implicit and rigid.

There is yet another approach. Define different methods for
different arguments:

def do_something_with_array(a)
# assume a is an array
end
def do_something_with_hash(h)
# assume h is a hash
end
def do_something_with_int(i)
# assume i is an int
end

do_something_with_array([1,2])
do_something_with_hash({1,2})
do_something_with_int(3)

This is of course doing by hand what static overloading does
'automatically'. In Ruby you still end up doing regular method
lookup for do_something_with_array and company.

The bottom line is that Ruby already provides several methods to deal
with complex argument lists. Adding some sort of class declarations
to formal arguments goes against the grain of Ruby's design with
little if any benefit to outweigh
the added complexity.

P.S. I seem to remember that there was a considerable amount of
criticism in the C++ community about static function overloading vs.
dynamic dispatch. I'm not sure what the situation is today.

Gary Wright
 
P

Phrogz

Shiwei said:
I think Function Overloading in C++ is very meaningful. And currently
the case for me is: How I can make use of method/function overloading
in Ruby?

Can you provide us with a few real-world cases where you would want to
use method overloading in C++? In Ruby, duck-typing does away with some
of those cases, and we can show you how.

If you show us what you are wanting to do, that makes it easier to
discuss the best ways to do it. (Unless, of course, you're just trying
to accomplish a checkmark in a feature list.)
 
R

Robert Klemme

I think Function Overloading in C++ is very meaningful. And currently
the case for me is: How I can make use of method/function overloading
in Ruby?

You can find a page linked from this Wiki page - currently our network
is shady so I cannot post the proper link:

http://www.rubygarden.org/ruby?RobertKlemme
Besides you might tell me Ruby is designed to exclude method
overloading, can you tell me sth more for the Overloading purpose?

I am not sure what exactly you mean by this.

Kind regards

robert
 
G

Gregory Brown

I think Function Overloading in C++ is very meaningful. And
currently the case for me is: How I can make use of method/
function overloading in Ruby?
Besides you might tell me Ruby is designed to exclude method
overloading, can you tell me sth more for the Overloading purpose?

This is a common question. The short answer is that function
overloading is based on knowing the static types of the actual
arguments to a method and in Ruby the entire notion of 'static types
of the actual arguments' is pretty much non-existent.

The longer answer is that for Ruby to provide some sort of
overloading a new syntax for method definition would be required and
then the method lookup algorithm would have to be updated. Warning:
pseudo code ahead.

def do_something( a as Array)
#...
end

def do_something( a as Hash)
#...
end

def do_something(a)
#...
end

do_something([1,2]) # as Array version
do_something({1,2}) # as Hash version
do_something(1) # unspecified version

This would really complicate the method dispatch mechanism as the
class of every argument would have to be examined *each* time any
method is called. I used literal arrays, hashes, and integers in the
example but in general they would
just be arbitrary expressions. In any case some sort of algorithm
would have to be run each time a method was called. This would
drastically increase method call overhead in Ruby.

This is a lot of work when the programmer can achieve the same goal
with the existing language quite concisely:

def do_something(a)
case a
when Array
# work with array
when Hash
# work with hash
else
# assume integer
end
end

Same effect, no language changes, and the algorithm is explicit and
flexible rather than implicit and rigid.

There is yet another approach. Define different methods for
different arguments:

def do_something_with_array(a)
# assume a is an array
end
def do_something_with_hash(h)
# assume h is a hash
end
def do_something_with_int(i)
# assume i is an int
end

def do_something(a)
send("do_something_with_#{a.class.name.downcase}"
end
 
G

Gregory Brown

Jeez! Sorry for the 3 emails, I must be tired. This is the little
hack I was trying to demonstrate:

seltzer:~/devel/parser-experiment/pegleg_evaluator sandal$ irb
def foo_array(a)
a + [1]
end => nil
def foo_string(a)
a << "apple"
end => nil
def foo(a)
send("#{a.class.name.downcase",a)
end
def foo(a)
send("foo_#{a.class.name.downcase}",a)
end => nil
foo([1,2,3]) => [1, 2, 3, 1]
foo("banana")
=> "bananaapple"


Though as others mentioned, a lot of this can be avoided by clever design. :)
 
G

gga

Shiwei Zhang ha escrito:
I think Function Overloading in C++ is very meaningful.

It isn't.
My requirement is: I've had a method "logon(uid,pswd, conn = nil, privilege = nil)", but I want to add > another method like "logon(easyconn)", where easyconn is in the format of
"uid/pswd@host:port/service_name [AS {SYSOPER|SYSDBA}]"

Ruby is such a complex language compared to C++ :)


class A
private

def _logon( uid, pwd, conn, privilege )
p uid, pwd, conn, privilege
end

public

def logon( uid, pwd = nil, conn = nil, privilege = nil )
if pwd == nil
# parse uid as "uid/pswd@host:port/service_name [AS
{SYSOPER|SYSDBA}]"
# and extract other vars.
uid =~ /(\S+)\/(\S+)\@(\S+:\S+)(?:\s+AS\s+(SYSOPER|SYSDBA))?/
uid, pwd, conn, privilege = $1, $2, $3, $4
end
_logon(uid, pwd, conn, privilege )
end

end

# user cannot see private method _logon
p A.instance_methods.grep /logon/

a = A.new
a.logon( 'gga', 'crap', 'host:2322')
a.logon( 'gga/crap@host:2322')
a.logon( 'gga/crap@host:2322 AS SYSOPER')
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top