# Implementing multiple "constructors" in ruby

**URL:** <https://www.ruby-forum.com/t/implementing-multiple-constructors-in-ruby/192364>\
**Category:** Ruby\
**Created:** [July 29, 2010, 2:54am UTC](https://www.ruby-forum.com/t/implementing-multiple-constructors-in-ruby/192364 "2010-07-29T02:54:44Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 29, 2010, 2:54am UTC](https://www.ruby-forum.com/t/implementing-multiple-constructors-in-ruby/192364/1 "2010-07-29T02:54:44Z")

</div>

So I have a class that I may want to instantiate multiple ways.

Here’s the signatures of the some so far:

def create\_from\_file(absolute\_filename, archive\_filename, fsg=nil,  
verbose=false, debug=false)  
def create\_from\_parts(archive\_filename, mtime, sha512hash)  
def create\_from\_string(str)

The canonical way to do this seems to be with branching in init. You  
look at the types of your arguments, and you sort of try and figure  
out in initialize a clever way to distinguish between them and invoke  
them correctly.

However, as you can see above, some of the methods are in a state of  
flux. Create\_from\_file has had several arguments appended to it, and  
the first argument of each method is a string (in the second two  
cases, I’m deserializing from a file, and having to convert to another  
class, like Pathname, just to call a constructor is annoying).  
Furthermore, I _have_ changed the types and order of arguments from  
time to time, this being a scripting language and all, and having to  
validate the distinguisher in initialize each time is kinda lame.

Type systems are also a slightly arcane subject, deliberately avoided  
in scripting languages, since not having to worry about them too much  
is perceived as a major benefit.

Further, should you change the signature of the methods, you have to  
go back and figure out whether that clever distinguisher in initialize  
actually still works. If you forget, which will likely happen just as  
often as C/C++ programmers forget to update function prototypes in  
header files, your run-time behavior will be unpredictable. I  
wouldn’t want to waste time debugging that.

What I did at first was avoid initialize do nothing (actually don’t  
even define one) and have each of the create\_from\_\* methods return  
self at the end. Then, I could do this:

m = Metadata.new().create\_from\_file(…)

Great, that’s pretty cool, but it’s a little tedious (less so if you  
leave off the empty parens).

So the other way I looked into was to create some static or class  
methods which created the object myself, and avoid new entirely.  
After all, there’s nothing too magic about new, and if it can’t do  
anything too fancy, emulating polymorphism in a scripting language  
using branching and RTTI is totally lame.

So I looked into this a bit, and I assume something like this could  
work:

def self.create\_from\_file(\*args)  
return self.new.create\_from\_file(\*args)  
end

Then I realized that I’ve got six methods now to do initialization;  
three class methods (which are a little obscure to noobs) and three  
instance methods. That’s a lot of verbosity… is there a better way?

Then it dawned on me:

def initialize(method=nil, \*args)  
case method  
when :file then create\_from\_file(\*args)  
when :parts then create\_from\_parts(\*args)  
when :string then create\_from\_string(\*args) # unused  
# if no method, do no intialization  
end  
end

This method seems to be the best of many worlds; I get a single  
initialize, I don’t have to do any retarded run-time type checking to  
emulate polymorphism, I can alter the signatures of the create\_from\_\*  
methods at will, and I never have to look at initialize, unless  
I want to add a new kind of initializer, which is a bit rare.

Some suggest that this violates the POLS/POLA, but it seems quite  
explicit to me (MUCH easier for a newbie to read than RTTI  
comparisons), more terse than multiple class constructors,  
substantially more robust in the face of changes to initializer type  
signatures than the magic initializer technique, scales well to large  
numbers of possible constructors, and is even backwards compatible  
with my old method (due to method=nil; you simply don’t pass any  
arguments and it gives you an uninitialized object; you can then call  
create\_from\_\* on it as before).

Opinions?

PS: As you see above, I’m passing verbose and debug around a lot and  
hate it. I’d like to use globals, but it seems kind of fugly to have  
classes accessing globals which are only used when the **FILE** ==  
$0. In fact, I always want verbose and debug off except when invoked  
as a script. Is there any cleaner way to deal with this?

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 29, 2010, 5:40am UTC](https://www.ruby-forum.com/t/implementing-multiple-constructors-in-ruby/192364/2 "2010-07-29T05:40:59Z")

</div>

On Wednesday, July 28, 2010 07:54:03 pm  
removed\_email\_address@domain.invalid  
wrote:

> So I have a class that I may want to instantiate multiple ways.
> 
> Here’s the signatures of the some so far:
> 
> def create\_from\_file(absolute\_filename, archive\_filename, fsg=nil,  
> verbose=false, debug=false) def create\_from\_parts(archive\_filename, mtime,  
> sha512hash)  
> def create\_from\_string(str)

Ah, that answers my question from earlier.

Do an options hash. Five arguments is too many.

Foo.new :absolute\_filename =\> ‘/foo/bar’, :archive\_filename =\> ‘bar’  
Foo.new :archive\_filename =\> ‘/foo/bar’, :mtime =\> 123, :hash =\> ‘abc’

Now you can trivially branch on them.

> So I looked into this a bit, and I assume something like this could  
> work:
> 
> def self.create\_from\_file(\*args)  
> return self.new.create\_from\_file(\*args)  
> end
> 
> Then I realized that I’ve got six methods now to do initialization;  
> three class methods (which are a little obscure to noobs)

They shouldn’t be. They’re just instance methods that happen to be on a  
Class  
object. Java’s “static” methods screw it up by putting them in the same  
namespace, that’s all.

> and three  
> instance methods. That’s a lot of verbosity… is there a better way?

Sure:

class Foo  
class \<\< self  
%w(file parts string).map{|x| :“create\_from\_#{x}”}.each do |type|  
define\_method type do |\*args|  
new.send type, \*args  
end  
end  
end  
end

Ok, that’s a little verbose. If this is a common pattern, you could  
extract it  
into a library so you could end up doing something like this:

class Foo

# implementation of the DefineMethods module left as an exercise

# to the reader…

include YourInitializers  
initializer :string do |str|  
…  
end  
initializer :parts do |archive\_filename, mtime, hash|  
…  
end

end

> Then it dawned on me:
> 
> def initialize(method=nil, \*args)  
> case method  
> when :file then create\_from\_file(\*args)  
> when :parts then create\_from\_parts(\*args)  
> when :string then create\_from\_string(\*args) # unused  
> # if no method, do no intialization  
> end  
> end

If you’re calling that directly, that’s a little gross…

> I don’t have to do any retarded run-time type checking to  
> emulate polymorphism,

In my last message, I suggested exactly that, but for a different  
reason. The  
main reason to do that would be convenience – usually, you’re testing  
between  
an options hash and something else that’s clearly not a hash, and not  
much  
beyond that.

But you’re right to be cautious – it gets ridiculous beyond one or two  
types.

> PS: As you see above, I’m passing verbose and debug around a lot and  
> hate it. I’d like to use globals, but it seems kind of fugly to have  
> classes accessing globals which are only used when the **FILE** ==  
> $0. In fact, I always want verbose and debug off except when invoked  
> as a script. Is there any cleaner way to deal with this?

What do you mean “as a script”?

Maybe not globals, then. Maybe module-specific constants. For example,  
hopefully, with a project this large, you’ve got a single module (or  
class,  
but probably module) serving as a base namespace:

module SomeBackupProgram  
DEBUG = false  
end

Even better, you could do this:

module A  
class \<\< self  
attr\_accessor :debug  
end

module B  
class \<\< self  
attr\_writer :debug  
def debug  
instance\_variable\_defined?(:@debug) ? @debug : A.debug  
end  
end

```
attr_writer :debug
def debug
  instance_variable_defined?(:@debug) ? @debug : self.class.debug
end

```

end  
end

I’m guessing there are libraries out there to make that less verbose,  
and it  
shouldn’t be too hard to write one yourself. The idea is that you could  
then  
set it globally:

A.debug = true

Or override it locally, while leaving the global setting alone:

A::B.debug = true

Or override it per-instance:

foo = A::B.new  
foo.debug = true

But, if you leave it alone, you get one global switch to turn on and  
off, and  
it’s available locally.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 29, 2010, 9:07am UTC](https://www.ruby-forum.com/t/implementing-multiple-constructors-in-ruby/192364/3 "2010-07-29T09:07:36Z")

</div>

On Thu, Jul 29, 2010 at 2:54 AM,  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> So I have a class that I may want to instantiate multiple ways.
> 
> Here’s the signatures of the some so far:
> 
> def create\_from\_file(absolute\_filename, archive\_filename, fsg=nil, verbose=false, debug=false)  
> def create\_from\_parts(archive\_filename, mtime, sha512hash)  
> def create\_from\_string(str)  
> […]  
> So the other way I looked into was to create some static or class  
> methods which created the object myself, and avoid new entirely.  
> After all, there’s nothing too magic about new, and if it can’t do  
> anything too fancy, emulating polymorphism in a scripting language  
> using branching and RTTI is totally lame.

> So I looked into this a bit, and I assume something like this could  
> work:
> 
> def self.create\_from\_file(\*args)  
> return self.new.create\_from\_file(\*args)  
> end
> 
> Then I realized that I’ve got six methods now to do initialization;  
> three class methods (which are a little obscure to noobs) and three  
> instance methods.

I wouldn’t create the instance methods, and do everything in the class  
methods:

def self.create\_from\_file(absolute\_filename, archive\_filename,  
fsg=nil, verbose=false, debug=false)  
#whatever processing of the arguments and then  
self.new standard\_params\_to\_initialize  
end

def self.create\_from\_parts(archive\_filename, mtime, sha512hash)  
#whatever processing of the arguments and then  
self.new standard\_params\_to\_initialize  
end

and so on. If the code is repetitive you can refactor the common parts.

Jesus.
