Class with Multi Constrcutor ( initialize )

Hey …
I’m Tryin’ to port Some Java Module into Ruby , but I have a small
probleme ,
how can I do to declare multi ‘initialize Method’ depending of the
number of user
argument

i.e in Java we can have a Class with many constructor
class myClass {

//…
public MyClass () { … } // Defualt One
public MyClass (Object obj1 ) { … }
public myClass ( Object obj1,Object obj2 …,Object objn) { … }
// …
}

I tried :
class myClass
def initialize ()
// …
end

def intialize ( value )
// …
end
end

but doesnt works !

I just wanna find a way to call the right constructor ( or initializer)
depending of the number of arguments

Thx :wink:

Hello Mido,

There are several solutions to this problem.

The first one is this equivalent of vaargs in C language

def initialize(*args)
args.each do |a|
puts a.class.inspect
end
end

The second one is to pass a hash or an array in parameter.

And the third is to put default values to your args:

def initialize(var1=’’, var2=0, var3=nil)
end

Hope i helped !

Kind regards

Mido P. wrote:

Hey …
I’m Tryin’ to port Some Java Module into Ruby , but I have a small
probleme ,
how can I do to declare multi ‘initialize Method’ depending of the
number of user
argument

i.e in Java we can have a Class with many constructor
class myClass {

//…
public MyClass () { … } // Defualt One
public MyClass (Object obj1 ) { … }
public myClass ( Object obj1,Object obj2 …,Object objn) { … }
// …
}

I tried :
class myClass
def initialize ()
// …
end

def intialize ( value )
// …
end
end

but doesnt works !

I just wanna find a way to call the right constructor ( or initializer)
depending of the number of arguments

Thx :wink:

Checking old emails on the matter, I like this approach a lot:

If you have different ways of constructing objects of a class, create
different class methods to do so. For example:

class MyClass
def self.from_x_y(x,y)
MyClass.new(x,y)
end

def self.default
MyClass.new(0,0)
end

def self.from_point§
MyClass.new(p.x, p.y)
end

def initialize(x,y)
@x = x
@y = y
end
end

This way you can have:

MyClass.default #=> 0,0
MyClass.from_x_y(10,20) # => 10,20
MyClass.from_point(Point.new(1,2)) #=> 1,2

Hope this helps,

Jesus.

On 27.01.2010 16:58, Pierre Lecocq wrote:

end

The second one is to pass a hash or an array in parameter.

And the third is to put default values to your args:

def initialize(var1=’’, var2=0, var3=nil)
end

Hope i helped !

A solution like this was proposed for overloading once but it does not
seem to be widely used:

irb(main):001:0> def overload(a)
irb(main):002:1> case a.map {|x|x.class}
irb(main):003:2> when [String]
irb(main):004:2> puts “a single string”
irb(main):005:2> when [Fixnum, String]
irb(main):006:2> puts a[1] * a[0]
irb(main):007:2> else
irb(main):008:2
raise ArgumentError, “can’t %p” % a
irb(main):009:2> end
irb(main):010:1> end
=> nil
irb(main):011:0> overload “foo”
a single string
=> nil
irb(main):012:0> overload 2, “foo”
foofoo
=> nil
irb(main):013:0> overload 2
ArgumentError: can’t 2
from (irb):8:in overload' from (irb):13 from /usr/local/bin/irb19:12:in
irb(main):014:0>

You can even shorten that to

case a.map(&:class)

Kind regards

robert

On Wed, Jan 27, 2010 at 4:34 PM, Mido P. [email protected]
wrote:

//…
end

def intialize ( value )
// …
end
end

but doesnt works !

I just wanna find a way to call the right constructor ( or initializer)
depending of the number of arguments

Ruby doesn’t support method overloading. If you need different
implementations just depending on the number of arguments you can do:

class MyClass
def initialize *args
case args.size
when 1
_init_1_param *args
when 2
_init_2_params *args

end
end

or you can do this:

class MyClass
def initialize(options = {})

and have the logic depend on the keys present in the hash

end
end

So you can call:

MyClass.new
MyClass.new(:obj1 => some_object, :obj2 => some_other_object)

Hope this helps,

Jesus.

On Jan 27, 2010, at 4:14 PM, Albert S. wrote:

Cool. Where is “Array#===” documented? I couldn’t find it.
Unfortunately Array#=== is just the same as Array#==, which is
why the argument list is mapped to class objects via #map in that
example from Robert.

There was a somewhat recent thread about changing Array#=== to
be an element-wise application of ===, which makes a lot of
sense to me.

Gary W.

Gary W. wrote:

On Jan 27, 2010, at 4:14 PM, Albert S. wrote:

Cool. Where is “Array#===” documented? I couldn’t find it.
Unfortunately Array#=== is just the same as Array#==,

So it isn’t cool. “when [Integer, Integer]” won’t match any integer
numbers :frowning:

There was a somewhat recent thread about changing Array#=== to
be an element-wise application of ===, which makes a lot of
sense to me.

to me too.

2010/1/28 Albert S. [email protected]:

be an element-wise application of ===, which makes a lot of
sense to me.

to me too.

Even if that would not happen you could do this and benefit from a
more efficient approach because tests are constants:

def MultiCheck(*a)
def a.===(b)
zip(b) {|x,y| return false unless x === y}
true
end
a.freeze
end

irb(main):023:0> T1 = MultiCheck String
=> [String]
irb(main):024:0> T2 = MultiCheck Fixnum, String
=> [Fixnum, String]
irb(main):025:0> def overload(a)
irb(main):026:1> case a
irb(main):027:2> when T1
irb(main):028:2> puts “a single string”
irb(main):029:2> when T2
irb(main):030:2> puts a[1] * a[0]
irb(main):031:2> else
irb(main):032:2
raise ArgumentError, “can’t %p” % a
irb(main):033:2> end
irb(main):034:1> end
=> nil
irb(main):035:0> overload “foo”
a single string
=> nil
irb(main):036:0> overload 2, “foo”
foofoo
=> nil
irb(main):037:0> overload 2
ArgumentError: can’t 2
from (irb):32:in overload' from (irb):37 from /opt/bin/irb19:12:in
irb(main):038:0>

:slight_smile:

Note, the same approach also works with regular expressions as
elements in the MultiCheck Array.

Cheers

robert

Robert K. wrote:

A solution like this was proposed for overloading once but it does not
seem to be widely used:

irb(main):001:0> def overload(*a)
irb(main):002:1> case a.map {|x|x.class}
irb(main):003:2> when [String]
irb(main):004:2> puts “a single string”
irb(main):005:2> when [Fixnum, String]

Cool. Where is “Array#===” documented? I couldn’t find it.

Thx Alot For Help :wink: