# Overloaded constructors in Ruby

**URL:** <https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558>\
**Category:** Ruby\
**Created:** [December 6, 2005, 2:24am UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558 "2005-12-06T02:24:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kheon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/48db29/32.png) [@kheon](https://www.ruby-forum.com/u/kheon)\
**Post date:** [December 6, 2005, 2:24am UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558/1 "2005-12-06T02:24:00Z")

</div>

I have a class that I want to have a number of overloaded constructors  
for.

I tried doing something like this:

class GravPoint  
def initialize()  
this(0, 0, 0, 0, 0)  
end

```
def initialize(x, y, strength)
    this(x, y, strength, 0, 0)
end

def initialize(x, y, strength, ctime, life)
    @x, @y, @strength, @ctime, @life = x, y, strength, ctime, life
end

```

end

When I then run GravPoint.new() I get the following error:

GravPoint.rb:23:in `initialize’: wrong number of arguments (0 for 5)  
(ArgumentError)

I think I understand the error, it’s expecting 5 arguments (based on the  
last constructor) but I don’t the “Ruby” way to set this up. What am I  
missing?

I was able to get this to work, but was hoping that I could do it in a  
format closer to the above to make it a little more flexible to use.

class GravPoint  
def initialize(x = 0, y = 0, strength = 0, ctime = 0, life = 0 )  
@x, @y, @strength, @ctime, @life = x, y, strength, ctime, life  
end  
end

Kyle H.  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![kheon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/48db29/32.png) [@kheon](https://www.ruby-forum.com/u/kheon)\
**Post date:** [December 6, 2005, 2:32am UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558/2 "2005-12-06T02:32:08Z")

</div>

i believe the way to do it is to use names parameters and/or default  
values.

---

<div class="post-metadata">

**Author:** ![kheon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/48db29/32.png) [@kheon](https://www.ruby-forum.com/u/kheon)\
**Post date:** [December 6, 2005, 2:36am UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558/3 "2005-12-06T02:36:11Z")

</div>

> **[WebMD - Better information. Better health.](https://www.webmd.com/?MethodOverloading)**
>
> The leading source for trustworthy and timely health and medical news and information. Providing credible health information, supportive community, and educational services by blending award-winning expertise in content, community services, expert...

---

<div class="post-metadata">

**Author:** ![kheon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/48db29/32.png) [@kheon](https://www.ruby-forum.com/u/kheon)\
**Post date:** [December 6, 2005, 3:37am UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558/4 "2005-12-06T03:37:04Z")

</div>

Timothy makes good points, but just so you understand how to write  
alernate constructors for Ruby there are two weys.

First one can define alternate constructors:

class GravPoint

```
# however you wish to name them...

def self.new_zero()
    new(0, 0, 0, 0, 0)
end

def self.new_lite(x, y, strength)
    new(x, y, strength, 0, 0)
end

def initialize(x, y, strength, ctime, life)
    @x, @y, @strength, @ctime, @life = x, y, strength, ctime, life
end

```

end

The other way is the use variable parameters. Something like:

```
 def initialize(*args)
    x, y, strength, ctime, life = 0,0,0,0,0
    case args.length
    when 0
      # good just the way it is, skip
    when 3
      x, y, strength = *args
    when 5
      x, y, strength, ctime, life = *args
    else
      raise ArgumentError
    end
    @x, @y, @strength, @ctime, @life = x, y, strength, ctime, life
 end

```

T.

---

<div class="post-metadata">

**Author:** ![kheon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/48db29/32.png) [@kheon](https://www.ruby-forum.com/u/kheon)\
**Post date:** [December 6, 2005, 8:29am UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558/5 "2005-12-06T08:29:35Z")

</div>

In article [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid),  
Kyle H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> this(x, y, strength, 0, 0)
> 
> ```
> 
> (ArgumentError)  
> @x, @y, @strength, @ctime, @life = x, y, strength, ctime, life  
> end

```
 def GravPoint.from_x_y_strength(x,y,strength)
   new(x,y,strength)
 end

```

> end

gp = GravPoint.new #matches your first constructor  
gp1= GravPoint.from\_x\_y\_strength 5.5,4.2,254 #matches your 2nd c’tor  
gp3= GravPoint.new(1,2,3,4,5) #matches your last c’tor

Phil

---

<div class="post-metadata">

**Author:** ![kheon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/48db29/32.png) [@kheon](https://www.ruby-forum.com/u/kheon)\
**Post date:** [December 6, 2005, 3:20am UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558/6 "2005-12-06T03:20:45Z")

</div>

Kyle H. wrote:

> ```
> end
> 
> ```
> 
> end

Actually, defining default values for arguments is a very “Ruby” way of  
handling this case. If the arguments have sensible default values, then  
I’d argue that it’s the best solution. You could also use a hash to  
simulate named parameters if that’s what floats your boat. Another very  
“Ruby” thing to do is to define multiple constructors with different  
names.

Something I’ve done is to define a “basic” constructor and then define  
one or more methods that modify the basic instance. For example, suppose  
you have two kinds of rectangles, a regular square-cornered rectangle  
and a rectangle with rounded corners. The difference between the two  
rectangles is that the rounded rectangle needs an extra 2 numbers to  
define the radii of the ovals that make up the corner. If you want a  
plain rectangle just call “new”. If you want a rounded rectangle, modify  
the newly-constructed instance by calling “rounded” on it.

class Rectangle  
def initialize(width, height)  
@width, @height = width, height  
end

```
def rounded(rx, ry)
   @rx, @ry = rx, ry
end

```

end

rect = Rectangle.new(20, 30)  
round\_rect = Rectangle.new(20, 30).rounded(2, 3)

---

<div class="post-metadata">

**Author:** ![kheon](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/48db29/32.png) [@kheon](https://www.ruby-forum.com/u/kheon)\
**Post date:** [December 6, 2005, 6:05pm UTC](https://www.ruby-forum.com/t/overloaded-constructors-in-ruby/49558/7 "2005-12-06T18:05:42Z")

</div>

Hi!

I guess you forgot a line, right?

class Rectangle  
def initialize(width, height)  
@width, @height = width, height  
end

```
def rounded(rx, ry)
   @rx, @ry = rx, ry
   self #<-FORGOTTEN
end

```

end

Sam
