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
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
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
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>
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.