I sometimes write modules that will only contain module methods (as opposed to module instance methods) (are there better names for these?). These modules should not be included in classes because that would have no effect and be misleading to a reader. So I'd like it to be as clear as possible to the reader that these modules contain no instance methods.
If I define all methods with .self
, then a reader has to inspect all methods to ensure that this module contains no instance methods. If I instead use class << self
or extend self
then it is automatic; as soon as the reader sees this, they know.
I think extend self
is best becuase with class << self
one has to find its corresponding end
; that is, it may not apply to all methods in the module.
So is it a good idea, and a best practice, to use extend self
in cases like this?
Also, is there any difference at runtime between enclosing all methods in class << self
as opposed to using extend self
?
I sometimes write modules that will only contain module methods (as opposed to module instance methods) (are there better names for these?).
Singleton, meaning a class with a single instance. Here that "single instance" is the Module instance.
If I define all methods with .self, then a reader has to inspect all methods to ensure that this module contains no instance methods
The module's documentation should make this clear. If the user of a module has to study the code to understand your module, that is a documentation failure.
extend self
do?So I'd like it to be as clear as possible to the reader that these modules contain no instance methods.
extend self
does the opposite. It makes all the instance methods also be class methods. It's equivalent to YourModule.extend(YourModule)
.
module YourModule
def some_method
23
end
extend self
end
Is the same as...
module YourModule
def some_method
23
end
end
YourModule.extend(YourModule)
Which is similar to...
module YourModule
def some_method
23
end
def self.some_method
23
end
end
Why would you do this? To allow both...
YourModule.some_method
and also...
class SomeClass
extend YourModule
end
SomeClass.some_method
There are edge cases where you might want this, but for general use I would argue this is an anti-pattern. The first is using a module as a singleton, the second is using the module as a mixin or trait. These are two rather different design goals for a module. Trying to be both will compromise the design of both.
Since the primary use case of being both a singleton and a mixin is an anti-pattern, I would argue use class << self
, with def self.method
occasionally, and module_function
and extend self
never.
class << self
Pros
attr_accessor
on the class.Cons
def self.method
.def self.method
Pros
Cons
self.
.attr_accessor
and friends on the class.extend self
Pros
YourModule.method
) and a mixin (extend YourModule
)... which is also a con.Cons
module_function
to extend self
, though doesn't explain why. For my guesses, see below.YourModule.method
) and a mixin (extend YourModule
). Those are two rather different use cases making this an anti-pattern.module_function
I've never heard of this either, but it came up when searching for extend self
. I would also say to never use this, use class << self
, but it's better than extend self
.
Pros
private
in that it affects all methods below it (though this is also a con, see below).Cons
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With