polymorphism and/or named parameters: the ruby way?

  • Thread starter Stephan Mueller
  • Start date
S

Stephan Mueller

Hello,

i am kind of a newbi, please forgive me if i am asking stale questions.

I want to adjust the initialization of an object according to the
parameters given to new.

My first idea was polymorphism I know from languages like java:

def initialize
puts("no param")
end

def initialize(p1) # p1 is an int
puts("do it like Beckham")
end

def initialize(p2) # p2 is a string
puts("do it like Ronaldo")
end

I understand of course that this can't work in ruby without strong
typing.

My next idea was to use named parameters:

def initialize(p1=nil, p2=nil)
unless p1.nil?
..
end
unless p2.nil?
..
end
end

# okay, let's make a baby!
MyClass.new(p1=500)


But as far as I could see in the pickaxe, there are no named parameters
in ruby (1.8 at least), right?

So please tell me, what is the ruby way to handle this kind of problem?
Use a single parameter and reflection?


Cheers,

- Thorsten
 
J

James Edward Gray II

Hello,

i am kind of a newbi, please forgive me if i am asking stale
questions.

I want to adjust the initialization of an object according to the
parameters given to new.

My first idea was polymorphism I know from languages like java:

def initialize
puts("no param")
end

def initialize(p1) # p1 is an int
puts("do it like Beckham")
end

def initialize(p2) # p2 is a string
puts("do it like Ronaldo")
end

I understand of course that this can't work in ruby without strong
typing.
[snip]

So please tell me, what is the ruby way to handle this kind of
problem?
Use a single parameter and reflection?

We can ask for a variable number of arguments, then check for the
various options. Something like:

def initialize( *args )
if args.empty?
puts "no param"
elsif args.size == 1 and args.first.is_a? Integer
puts "do it like Beckham"
elsif args.size == 1 and args.first.is_a? String
puts "do it like Ronaldo"
else
raise ArgumentError, "Invalid initialization for #
{self.class}."
end
end

Hope that helps.

James Edward Gray II
 
E

Eric Mahurin

--- Stephan Mueller said:
Hello,
=20
i am kind of a newbi, please forgive me if i am asking stale
questions.
=20
I want to adjust the initialization of an object according to
the
parameters given to new.
=20
My first idea was polymorphism I know from languages like
java:
=20
def initialize
puts("no param")
end
=20
def initialize(p1) # p1 is an int
puts("do it like Beckham")
end
=20
def initialize(p2) # p2 is a string
puts("do it like Ronaldo")
end
=20
I understand of course that this can't work in ruby without
strong
typing.
=20
My next idea was to use named parameters:
=20
def initialize(p1=3Dnil, p2=3Dnil)
unless p1.nil?
..
end
unless p2.nil?
..
end
end
=20
# okay, let's make a baby!
MyClass.new(p1=3D500)
=20
=20
But as far as I could see in the pickaxe, there are no named
parameters
in ruby (1.8 at least), right?
=20
So please tell me, what is the ruby way to handle this kind
of problem?
Use a single parameter and reflection?


What you are talking about is really method overloading not
polymorphism in my opinion.

My take on the "ruby way" is to not overload methods by type
like you can easily do in java. Instead you just make multiple
distinct methods with each method taking its own "type". This
give maximal flexibility with duck-typing.

There is no reason you can't make multiple new type class
methods that call the normal "new" method - you wouldn't need
an initialize in that case.

The closest you can come to named parameters is by using a hash
(right now, at least):

def test(hash)
if hash[:p1]
...
elsif hash[:p2]
...
end
end

test:)p1=3D>500)

In ruby 1.9 you can use the shortcut test(p1: 500) when you
want the key to be a symbol.



=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20
 
S

Stephan Mueller

Hi Eric,

* Eric Mahurin said:
What you are talking about is really method overloading not
polymorphism in my opinion.

Yes, I agree. :)
My take on the "ruby way" is to not overload methods by type
like you can easily do in java. Instead you just make multiple
distinct methods with each method taking its own "type". This
give maximal flexibility with duck-typing.

There is no reason you can't make multiple new type class
methods that call the normal "new" method - you wouldn't need
an initialize in that case.

Something like this?

class MyClass

def new_s(str)
me = super
# do sth with str
return me
end

def new_i(int)
me = super
# do sth with int
return me
end

...
The closest you can come to named parameters is by using a hash
(right now, at least):

def test(hash)
if hash[:p1]
...
elsif hash[:p2]
...
end
end

test:)p1=>500)

Okay, looks quite good for me. Not much more effort than real named
params.

Thanks!

Steph.
 
S

Stephan Mueller

Hi James,

* James Edward Gray II said:
We can ask for a variable number of arguments, then check for the
various options. Something like:

def initialize( *args )
if args.empty?
puts "no param"
elsif args.size == 1 and args.first.is_a? Integer
puts "do it like Beckham"
elsif args.size == 1 and args.first.is_a? String
puts "do it like Ronaldo"
else
raise ArgumentError, "Invalid initialization for # {self.class}."
end
end

Hope that helps.

Yes, thanks a lot. Though i think i like the approach using a hash
mentioned in another post a little bit more because it can do the same as
this one plus some sort of named params. It depends on the precise
situation I guess.


Cheers,

Steph.
 
E

Eric Mahurin

--- Stephan Mueller said:
Hi Eric,
=20

=20
Yes, I agree. :)
=20
=20
Something like this?
=20
class MyClass
=20
def new_s(str)
me =3D super
# do sth with str
return me =20
end
=20
def new_i(int)
me =3D super
# do sth with int
return me =20
end
=20
... =20

I was thinking something like this (I don't think the above
does what you want):

class MyClass
def self.new_s(s)
obj =3D new
# do sth with s and obj
obj
end
def self.new_i(i)
obj =3D new
# do sth with i and obj
obj
end
end



=09
____________________________________________________
Start your day with Yahoo! - make it your home page=20
http://www.yahoo.com/r/hs=20
=20
 
R

Reyn Vlietstra

Comming from a C++ background I was also facing the same issue with
methods, not initialize specifically.
I found myself creating methods like:=20
* delete_object_by_class(someclass)
* delete_object_by_class_name(classname)
* delete_object_by_name(name)
* etc.

The people on #ruby-lang helped me understand closures a bit better.

So now instead of doing: delete_object_by_class(someclass)
I do, delete_object{|o| o.class =3D=3D someClass}

By passing the test condition to the method through a block I cut out
quite alot of bad looking code.

=20
I was thinking something like this (I don't think the above
does what you want):
=20
class MyClass
def self.new_s(s)
obj =3D new
# do sth with s and obj
obj
end
def self.new_i(i)
obj =3D new
# do sth with i and obj
obj
end
end
=20
=20
=20
=20
____________________________________________________
Start your day with Yahoo! - make it your home page
http://www.yahoo.com/r/hs
=20
=20
=20


--=20
Reyn Vlietstra
 
S

Stephan Mueller

Hi Eric,

* Eric Mahurin said:
I was thinking something like this (I don't think the above
does what you want):

class MyClass
def self.new_s(s)
obj = new
# do sth with s and obj
obj
end
def self.new_i(i)
obj = new
# do sth with i and obj
obj
end
end

You are right. My code was plain wrong. Without using self.new... the
method is unknown to Class and super can't work because in Class there is
no new_i or new_s. Ouch!

Your code works as intended. Thanks!


Steph.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top