Including module in file vs. in class (Ruby Mixins): What is better? - ruby

In Ruby I want to put some helpers in an extra-module and file. I will use it at the model-level, so i put
include MyHelper
class Shop
...
end
I now realize this can also be done like so:
class Shop
include MyHelper
...
end
Can anyone explain me more about the differences? Is the second version always the better choice?

The difference is that in the first case you include the helper in the global namespace. I can't think of a case in which that is a good idea.
In the latter case you include the helper in the "namespace" of the class. The (instance) methods defined in the module are now available to instances of the Shop class.

Related

Instance Functions vs Class Functions in Ruby

I have two versions of a simple program that accomplishes the same thing. I have some questions.
When should I use class functions over instance functions?
Are there any performance benefits of using class vs instance functions? Does one use more resource than the other given everything else constant.
Is defining a class function with self the same as defining it with the module's name (version 2 question)
Version 1: instance functions
I have a file called pastries.rb that contains:
module Pastries
def description
return "I am a pastry!"
end
end
Then in another file called main.rb, I have:
require 'pastries'
include Pastries
puts "With include: #{description}" # With include: I am a pastry!
Version 2: class functions
pastries.rb:
module Pastries
# Are the following equivalent?
# def self.info
# return "I am a pastry!"
# end
def Pastries.description
return "I am a pastry!"
end
end
main.rb:
require 'pastries'
puts "WITHOUT include: #{Pastries.description}" # WITHOUT include: I am a pastry!
Any feedback is appreciated. I am a newbie both on stackoverflow and in Ruby, so correction of posting style or other critiques are welcomed as well.
To start off, functions in Ruby are called Methods.
In version 1, you are using the Module with an instance method, which can be used in mixins (i.e., it is mixed in to a class) as above. Here, you are mixing it with the top-level object class in main.rb.
In version 2, you are using the Module(s) with class method(s), where the module acts as a namespace to avoid namespace collisions for these methods when it is used along with other modules and classes.
To your particular questions:
1. When should I use class functions over instance functions?
Class level methods within modules may be used when you want to provide direct access to a module's methods without the need of instantiating a class object (for ex. standalone libraries) or when you want to use the method in the scope of the object where it is mixed in.
Instance methods should be used when you want to call the module's method via a class object where it is mixed in (for ex. to provide additional functionality for a class and serve a mechanism for a class similar to multiple inheritance)
2. Are there any performance benefits of using class vs instance functions? Does one use more resource than the other given everything else constant.
As explained in 1 and 3, the benefits depend on the required usage. For memory consumption, AFAIK, no countable differences.
3. Is defining a class function with self the same as defining it with the module's name (version 2 question)
Not exactly. When you define a module method with module's name, it'll always be accessible in the scope of the module, while a module method defined with self will be accessed in the scope of the object from where it has been called. See the following answer for a detailed description: Trying to understand use of self.method_name vs. Classname.method_name in Ruby
Hope this helps, Cheers.

Ruby syntax, nested modules or classes

I am new to Ruby but have been looking through some source code. I came across the kind of structures shown below in some source code (names of modules, classes not the real ones)
module ModuleOne
class MyClass
module CommonModule
# code ....
end # module CommonModule
end # class MyClass
end # module ModuleOne
or this example
module ModuleOne
class MyClass
class MyClassTwo
#code ............
end #class MyClassTwo
end #class MyClass
end #module ModuleOne
From my reading so far I know about wrapping classes in modules, but I haven't heard of the kinds of wrapping (modules inside modules or classes in classes for example) shown above. Can I ask,
1. Is this good practice and commonly done ?
2. What is the advantage of structuring code in this way ?
Thanks for any comments or pointers
Dave
Nesting is done to encapsule constants, which modules are special cases of. In other words, they are used for namespacing. When you want a particular module to be accessible only within the context of a certain module, you should do nesting. By doing so, that module will not be accessible by default from outside; you would have to prefix the namespace to do so. When you have too many layers of nesting, or when the module body is long, it would become hard to follow it in the code, so a good way in such case is to write the whole namespace.
module ModuleOne
...
end
class ModuleOne::MyClass
...
end
class ModuleOne::MyClass::MyClassTwo
...
end

Refer to method in module with same name as class

I have a class and a module which have the same names:
module Pushover
def configure
..
end
end
module MyModule
class Pushover
def blah
Pushover.configure
end
end
end
This doesn't work because the Pushover.configure call directs to the containing class. Now, an obvious fix would be to rename the class. However, the Module is from a gem and the class conforms to a naming convention required in a DSL. So ideally they should both stay the same. I could also create a second helper class and call via that, but that all seems a little hacky. My preferred solution would be to directly reference the module method.
All the existing questions around this area seem to be disambiguating in the opposite direction - i.e. they want to get the class reference not the module.
Is there any way for me to inform Ruby that I mean the module rather than the class when I specify Pushover?
If you don't want to look up the constant relative to the current scope, just use an absolute path:
::Pushover.configure

What is the difference beween adding a Module to World vs adding a Class in Cucumber?

For example.
When working with ruby on rails in cucumber you can do both
Example with a Class
class Awesome
def thing
end
end
World{ Awesome.new }
Example with a Module
module Awesome
def thing
end
end
World(Awesome)
Why would I use one over the other? What is the difference?
No difference because class's class is inherited from module's class. The only difference is that you can't instantiate the module. Usually in cucumber you don't need to do it so modules are just ok. If you somehow need to include something into the world and somewhere else you have to make an instance - you can go with class but I hardly can imagine such situation,

When to use a module, and when to use a class

I am currently working through the Gregory Brown Ruby Best Practices book. Early on, he is talking about refactoring some functionality from helper methods on a related class, to some methods on module, then had the module extend self.
Hadn't seen that before, after a quick google, found out that extend self on a module lets methods defined on the module see each other, which makes sense.
Now, my question is when would you do something like this
module StyleParser
extend self
def process(text)
...
end
def style_tag?(text)
...
end
end
and then refer to it in tests with
#parser = Prawn::Document::Text::StyleParser
as opposed to something like this?
class StyleParser
def self.process(text)
...
end
def self.style_tag?(text)
...
end
end
is it so that you can use it as a mixin? or are there other reasons I'm not seeing?
A class should be used for functionality that will require instantiation or that needs to keep track of state. A module can be used either as a way to mix functionality into multiple classes, or as a way to provide one-off features that don't need to be instantiated or to keep track of state. A class method could also be used for the latter.
With that in mind, I think the distinction lies in whether or not you really need a class. A class method seems more appropriate when you have an existing class that needs some singleton functionality. If what you're making consists only of singleton methods, it makes more sense to implement it as a module and access it through the module directly.
In this particular case I would probably user neither a class nor a module.
A class is a factory for objects (note the plural). If you don't want to create multiple instances of the class, there is no need for it to exist.
A module is a container for methods, shared among multiple objects. If you don't mix in the module into multiple objects, there is no need for it to exist.
In this case, it looks like you just want an object. So use one:
def (StyleParser = Object.new).process(text)
...
end
def StyleParser.style_tag?(text)
...
end
Or alternatively:
class << (StyleParser = Object.new)
def process(text)
...
end
def style_tag?(text)
...
end
end
But as #Azeem already wrote: for a proper decision, you need more context. I am not familiar enough with the internals of Prawn to know why Gregory made that particular decision.
If it's something you want to instantiate, use a class. The rest of your question needs more context to make sense.

Resources