Here’s a little problem I ran into in some old code of mine.
Sometimes we’ve got methods where we want to return a new instance of the same class.
It’s tempting to write the following code:
>> class A >> def a_whole_new_me >> A.new >> end >> end
Sure enough, that seems to work:
>> a = A.new >> a.class => A >> a.a_whole_new_me.class => A
So what’s wrong with it? We forgot about subclasses!
>> class B < A; end >> b = B.new >> b.class => B >> b.a_whole_new_me.class => A
If we’re expecting a copy of B and get A, this is certainly going to cause trouble, but the scary part is it might not right away (since B usually has all of A’s methods, but not necessarily the other way around)
Luckily, this is easy to fix, just use self.class
>> class A >> def a_whole_new_me >> self.class.new >> end >> end >> a = A.new >> a.class => A >> a.a_whole_new_me.class => A >> class B < A; end >> b = B.new >> b.class => B >> b.a_whole_new_me.class => B
This practice is usually a good idea whenever we want to refer to our class object. Rather than making things rigid, if you use self.class when possible, your code will be easier to extend and behave better in general. Of course, your mileage may vary depending on your task.