[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Polymorphism

Michael Satterwhite

4/20/2009 4:20:00 PM

As much as I like Ruby, I do miss the polymorphic behavior of routines
in Java and C++. There are frequently times in which it would be useful
to have constructors (or routines) that take different arguments. I do
see some constructors that may take arguments of different types, so I
know people are doing it, but I'm curious as to how.

The only way I can think of is to start the routine with a check such as
"var.class.name == <whatever>" and have different logic within the
routine that is taking different argument types. Would some of you let
me know of your techniques? I'm anxious to learn.

---Michael
--
Posted via http://www.ruby-....

12 Answers

Phlip

4/20/2009 4:23:00 PM

0

Michael Satterwhite wrote:

> As much as I like Ruby, I do miss the polymorphic behavior of routines
> in Java and C++. There are frequently times in which it would be useful
> to have constructors (or routines) that take different arguments. I do
> see some constructors that may take arguments of different types, so I
> know people are doing it, but I'm curious as to how.

That's "overloading", not "polymorphism".

You do that in Ruby like this:

def zone(*args)
args.each do |arg|
case arg
when String
string_zone(arg)
when Fixnum
fixnum_zone(arg)
when MechaBattle
mecha_battle_zone(arg)
end
end
end

From here, learn what real polymorphism is! You prob'ly already use it...

--
Phlip

Mike Stephens

4/22/2009 10:58:00 PM

0

Phlip wrote:

>
> That's "overloading", not "polymorphism".
>

Before this thread I thought I understood polymorphism. Suddenly
confused, I went off to Wikipedia and there are all sorts of arcane
stuff there. I'm impressed how many technical terms people can use.

Here's what I think it means: You can declare procedures (and, by
extension, operators) that have identical names (eg 'hire', 'sort', '+')
but behave differently depending on the nature of the object concerned.
This saves you generating unique names for each type of data. So
polymorphic means 'behaving differently in different situations'.

If this is the case (forget all the different ways you might achieve
that), then Ruby must deliver mainstream polymorphism because it uses
classes. A class encapsulates procedures and therefore allows names to
be re-used. The appropriate behaviour is selected by the type of the
object concerned.

Again if this simplistic view is correct, your examples are not to do
with Ruby and polymorphism, they are to do with making classes contain
more than one type of object (and why would you feel entitled to do
that?)
--
Posted via http://www.ruby-....

John Maclean

4/22/2009 11:16:00 PM

0

2009/4/22 Mike Stephens <rubfor@recitel.net>:
> Phlip wrote:
>
>>
>> That's "overloading", not "polymorphism".
>>
>
> Before this thread I thought I understood polymorphism. Suddenly
> confused, I went off to Wikipedia and there are all sorts of arcane
> stuff there. I'm impressed how many technical terms people can use.
>
> Here's what I think it means: You can declare procedures (and, by
> extension, operators) that have identical names (eg 'hire', 'sort', '+')
> but behave differently depending on the nature of the object concerned.
> This saves you generating unique names for each type of data. So
> polymorphic means 'behaving differently in different situations'.
>
> If this is the case (forget all the different ways you might achieve
> that), then Ruby must deliver mainstream polymorphism because it uses
> classes. A class encapsulates procedures and therefore allows names to
> be re-used. The appropriate behaviour is selected by the type of the
> object concerned.
>
> Again if this simplistic view is correct, your examples are not to do
> with Ruby and polymorphism, they are to do with making classes contain
> more than one type of object (and why would you feel entitled to do
> that?)
> --
> Posted via http://www.ruby-....
>
>


May be a time to look at the So-called GOf "Gang of Fours"'s Design Templates.


--
John Maclean
07739 171 531
MSc (DIC)

Timezone: GMT

Robert Klemme

4/23/2009 7:55:00 AM

0

2009/4/23 Mike Stephens <rubfor@recitel.net>:
> Phlip wrote:
>
>>
>> That's "overloading", not "polymorphism".
>>
>
> Before this thread I thought I understood polymorphism. Suddenly
> confused, I went off to Wikipedia and there are all sorts of arcane
> stuff there. I'm impressed how many technical terms people can use.
>
> Here's what I think it means: You can declare procedures (and, by
> extension, operators) that have identical names (eg 'hire', 'sort', '+')
> but behave differently depending on the nature of the object concerned.

More precisely: they must have identical /signatures/. This is polymorphism.

If only the name is identical, it is /overloading/. Overloading can
occur in a single class or in a class hierarchy. Ruby does not have
built in mechanisms for overriding but it can be mimicked. Simple
example

def foo(x)
case x
when Fixnum
self + x
when String
"You sent: %p" % x
else
raise NameError, "No overriden version of foo(%p)" % x.class
end
end

Of course the story gets more complicated if you have different length
argument lists etc. I tend to rather use different method names if
there is indeed different behavior. If all arguments can be coerced
into uniform types and the method just needs those types then of
course you can live with one method, e.g.

def bar(n)
n = case n
when String: n
when Float: "%4.1f" % n
when Fixnum: "%4d" % n
else n.to_s
end
n.scan /\d+/
end

Then there is also /overriding/: a class which provides a method
implementation of a super class method with identical signature is
said to /override/ that method. Note that overriding and polymorphism
can come together but they do not need to! (see again C++)

> This saves you generating unique names for each type of data. So
> polymorphic means 'behaving differently in different situations'.

Right.

> If this is the case (forget all the different ways you might achieve
> that), then Ruby must deliver mainstream polymorphism because it uses
> classes.

The must have criterion for polymorphism is not classes but late
binding. You can see that nicely in C++ where you need to declare
methods "virtual" in order to get polymorphism.

> A class encapsulates procedures and therefore allows names to
> be re-used. The appropriate behaviour is selected by the type of the
> object concerned.
>
> Again if this simplistic view is correct, your examples are not to do
> with Ruby and polymorphism, they are to do with making classes contain
> more than one type of object (and why would you feel entitled to do
> that?)

I am not sure which examples you are referring to.

Kind regards

robert


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

Rick DeNatale

4/23/2009 2:31:00 PM

0

On Thu, Apr 23, 2009 at 3:54 AM, Robert Klemme
<shortcutter@googlemail.com> wrote:

> More precisely: they must have identical /signatures/. This is polymorphism.
>
> If only the name is identical, it is /overloading/. Overloading can
> occur in a single class or in a class hierarchy.
...

> Of course the story gets more complicated if you have different length
> argument lists etc.

I'm not disagreeing with you Robert, but I need to point out that the
concept or equivalent of the 'name' of a method varies with the
language, to avoid confusion, let's call the token which identifies a
group of polymorphic methods the method token.

In Ruby, the method token is quite simple, it's a simple identifier.

def foo
end

the name of this method is foo.

In Smalltalk, or Objective-C, the token (called a method selector in
Smalltalk, or just a selector in Objective-C) is either as simple
identifier for a method with no parameters which Smalltalk calls unary
messages, or the concatenation one or more simple identifiers each
followed by a colon one for each parameter called keyword messages in
Smalltalk.

Smalltalk also has binary messages/selectors for things like
arithmetic and comparison methods, these selectors are s string of
characters from a restricted set, e.g. + or <=

MacRuby uses a hybrid of the Ruby and Objective-C selector, in
MacRuby, a call of the form

x.foo(1, :bar => 2, :baz => 3)
or using the Ruby 1.9 syntax
x.foo(1, bar: 2, baz: 3)

uses a selector of foo:bar:baz mapping the Ruby practice of using a
final hash parameter to provide 'keyword arguments' to Objective-C
style selectors (actually directly to Objective-C selectors). I'm not
sure what tricks MacRuby has up its sleeve for dealing with the fact
that in normal Ruby

x.foo(1, :bar => 2, :baz => 3)
and
x.foo(1, :baz => 3, :bar => 2)

invoke the same method, and have the same effect.

In a statically typed OO language like C++ or Java, the method token
also tied to the highest class in the hierarchy of a type which
introduces a name. If overloading/generics are supported by the
language then it may also be tied to the parameter types.

It's these kind of subtleties which confound multi-language discussions.

--
Rick DeNatale

Blog: http://talklikeaduck.denh...
Twitter: http://twitter.com/Ri...
WWR: http://www.workingwithrails.com/person/9021-ric...
LinkedIn: http://www.linkedin.com/in/ri...

Albert Schlef

4/23/2009 11:24:00 PM

0

Robert Klemme wrote:
>
> def foo(x)
> case x
> when Fixnum
> self + x
> when String
> "You sent: %p" % x
> else
> raise NameError, "No overriden version of foo(%p)" % x.class
> end
> end
>

I should mention that simple /overloading/ can be achived by delegating
the action to the 'x':

def foo(x)
case x
when Fixnum
self + x
when String
"You sent: %p" % x
else
x.foo # Note this line!
end
end

Ruby's core library uses this technique in several places.
--
Posted via http://www.ruby-....

Mike Stephens

4/24/2009 6:33:00 AM

0

Robert Klemme wrote:
>
>
> The must have criterion for polymorphism is not classes but late
> binding.

I think this is where we disagree. You seem to be saying polymorphism is
the ability for a piece of code to handle objects of differing types. I
don't think that is necessary. It's perfectly alright for each
object-type to have it's own code to handle a method. The only thing
that needs to be shared is the name, not its implementation. This works
just fine in early-binding contexts.
--
Posted via http://www.ruby-....

Mike Stephens

4/24/2009 10:30:00 AM

0


> 2009/4/24 Mike Stephens <rubfor@recitel.net>:

I've just noticed my email address gets inserted in responses to my
posts. No wonder I get spam. Is this a known fault?
--
Posted via http://www.ruby-....

Robert Klemme

4/24/2009 11:16:00 AM

0

2009/4/24 Mike Stephens <rubfor@recitel.net>:
>
>> 2009/4/24 Mike Stephens <rubfor@recitel.net>:
>
> I've just noticed my email address gets inserted in responses to my
> posts. No wonder I get spam. Is this a known fault?

As soon as you post to public forums your email address is in public.
It does not matter whether it is inserted into replies by others.
That's why I use a GMail account for public communication...

And please do not hijack the thread for a complete different topic.

Cheers

robert

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

Mike Stephens

4/24/2009 12:56:00 PM

0

Robert Klemme wrote:

>
> And please do not hijack the thread for a complete different topic.
>
> Cheers
>
> robert

You could make that remark for virtually any topic except....
polymorphism
--
Posted via http://www.ruby-....