The more objects I build, the more I am realising that I need to keep my initialize methods simple. Not doing so, leads to problems later on.
The key is in the name: best practice is to keep the initialize method to just initially loading instance variables.
An example
Suppose I want to build a class to translate Spanish text into English.
The wrong way to do it
def initialize(text)
super(to_english(text))
end
.......
def to_english(text)
EasyTranslate.translate(text, :to => :en)
end
end
Translate.new('Este es texto') ----> 'This is text'
So what is the problem
This solution works. However, it doesn’t scale.
What if I want to use Translator to translate Spanish to German, or English to Spanish? My initialize method assumes that I’ll only be translating to English. As well as adding code to do the new translation code, I’d also have to modify initialize to work with the new code.
This is not too much of a problem with such a simple class, but what if there were many methods and each of them relied on the initialize method’s modification of the text as a starting point. I’d have to modify all those methods too.
Also it is not easy to test any instance method without processing the to_english method. It then becomes difficult to isolate a method test to simply testing the actions of that method.
A better solution
def initialize(text)
@text = text
end
..............................
def to_english
EasyTranslate.translate(@text, :to => :en)
end
end
Now if I want to add a method to translate to German, it is just a case of adding the new method.
The downside, is when I use the code, the input is now more verbose:
However I can easily fix that with a class method:
new(text).to_english
end
Personally, I might not keep the class and instance methods using the same name, but this demonstrates how easy it is to create more succinct usage: