Here is “def self.method” style:
2 Pros of “def self.method” style
3 Pros of “class << self” style
# Style #1 class User < ActiveRecord::Base def rating end def self.most_popular end def title_with_rating end def self.the_king end endAnd the same example for “class << self” style:
# Style #2 class User < ActiveRecord::Base class << self def most_popular end def the_king end end def rating end def title_with_rating end end
Pros of “def self.method” style
1. It’s shorter and easier to add one methodIt’s obvious, that Style #1 is two lines shorter due to the “class << self; end” part. This difference is noticeable for one/two methods. Also, it’s easier to add first class method because you don’t have to type “class << self” wrapper.
2. More simple for newbiesUsually Style #2 looks more exotic than Style #1; and, at first, the “class << self” part looks a little bit awkward.
Pros of “class << self” style
1. Class and instance methods are separatedGlancing over class definition, in Style #1 it’s hard to say, whether it’s a class or instance method. You need to focus on name part. On the other side, in Style #2 indentation and “class << self” wrapper clearly says who is who.Another benefit of Style #2 – it’s easy to see amount of class and instance methods. They are not intermixed. Without clear separation it’s harder to work with class – you need to go over mix of methods and look for the required method.Of course, you can take convention, for grouping class methods in one place, but it’s another rule, which should be followed by all, and it’s so easy to violate it occasionally. With Style #2 is much harder to accidentally create another “class << self” scope.
2. Easier to add batch of methodsWhat I especially appreciate in Style #2 – it’s easiness of adding new class methods. While Writing a new method, you shouldn’t be focused on adding “self.”-part in name. Class and instance method definition have the same syntax.When I started my way in Ruby, it frustrated me a lot when I added class method and it didn’t work. And only then I realised that I actually forgot to add “self.”-prefix.I strongly believe that a programmer should focus more on what he does and less on various language quirks. And after I switched to Style #2, these kinds of errors just disappeared from everyday coding.
3. Simpler search of method definition“grep”-ing for some method is simpler to always search by “def name” combination. Style #1 also requires search by “def self.name”. This item is not a showstopper, but I run into this issue from time to time while searching through a code of different gems.
4. Simpler refactoringWhat is started as object-oriented class can turn out to be a procedural module with a bunch of functions. To refactor instance methods into class methods you just need to add “class << self” wrapper and adjust indentation, which can be easily done in any editor.On the other side, Style #1 requires to put “self.”-prefix in every method, which is tedious and can’t be archived with usual means.Also, there is a case when you go into the opposite direction. Thing, which started as procedural module use some common context and should be refactored into class with instance methods. And again Style #1 requires removing of “self.”-prefix from all names, when in Style #2 you just remove “class << self / end” wrapper and adjust indentation.
ConclusionIt’s clearly seen, that “class << self” style has much more benefits than more commonly used “def self.method”. For me, the most crucial part is clear separation between class and instance stuff – because it improves code readability. I also like that Style #2 removes one class of errors from my Ruby programming.Generally, we stick to the rules below while using it:
- Create “class << self” wrapper even for one method
- Put class-methods part at the top of the class