Keep in mind that in Ruby, classes and modules are just ordinary objects that happens to be instances of the classes Class and Modules respectively.
So for all practical purposes, if you define a module it is not much different than if you define a class, and then instantiate a single object (it is slightly different in that your object will be an instance of your class rather than of the class Class).
Modules are namespaces for Ruby (and pretty much only differs from classes in that you can't create instances of modules)
What you describe above is done with modules:
module UserContentSpamChecker
def is_spam?(content)
...
end
end
class MyOther Class
include UserContentSpamChecker
def foo
is_spam?(content)
end
end
If you want to be able to alias it, you'd do it with a method:
module UserContentSpamChecker
def self.is_spam?(content) # note the "self." to define a method callable on the UserContentSpamChecker object itself (of class Module)
...
end
end
class MyOther Class
def spam_checker; UserContentSpamChecker; end
def foo
spam_checker.is_spam?(content)
end
end
(or you could do it with a class variable or class instance variable - example class variable:)
class MyOtherClass
@@spam_checker = UserContentSpamChecker
def foo
@@spam_checker.is_spam?(content)
end
end
I find that modules are good to add behaviour to an object like Enumerable but I don't find them practical as a namespace holder.
Including is an all or nothing operation. In your first example #is_spam? is now also a public method of MyOtherClass. The other issue with module includes is that method name collisions are also much harder to debug.
I also like your second example but I think it would be clearer if :spam_checker had a dedicated semantic. Something like:
class Module
def import(name, obj); define_method(name) { obj }; protected(name); end
end
So for all practical purposes, if you define a module it is not much different than if you define a class, and then instantiate a single object (it is slightly different in that your object will be an instance of your class rather than of the class Class).
Modules are namespaces for Ruby (and pretty much only differs from classes in that you can't create instances of modules)
What you describe above is done with modules:
If you want to be able to alias it, you'd do it with a method: (or you could do it with a class variable or class instance variable - example class variable:)