Vishal G
Vishal G

Reputation: 1531

RIght way of writing module methods in Ruby

what is right way of writing module? is it only used to stock some peace of code to minimize the number of lines, or is it something much more important than that

I have used and seen ways of writing module, I am working on setting up correct way to define and standardised module. this example is kind of controller code that we use in rails

Way 1 :-

module B
  extend ActiveSupport::Concern

  def process_items
    # do somthing...
    @items.pluck(:names)
  end
end


Class A
  include B
  
  def index
    @items = Item.all
    @item_names = process_items
  end
end

Way 2 :-

module B
  extend ActiveSupport::Concern

  def process_items(items)
    # do somthing...
    items.pluck(:names)
  end
end


Class A
  include B
  
  def index
    @items = Item.all
    @item_names = process_items(@items)
  end
end

Way 1 :-

  1. When I see this independently, its not much readable as I don't know how @items appeared in this method
  2. Unit testing would be hard for method as its dependent

Way 2 :-

  1. Looking at method I can see input is coming we are processing it and returning it back (readablity is good)
  2. Unit testing is easy to this, we wll call method pass what it needs and expect

The way I see modules should be independent, self explanatory, it should be generic so that can be used in any class, kind of helpers. But other way could be dependent on where we use modules

We are using modules like in rails

  1. We use conccern in models, when we call module method we can use self.<field> we don't need to pass anything because instance variable is supposed to be accesssable in every instance method
  2. View helpers are modules I see they put logic into it hard to understand how the variable come from may be instance variable or params, what about making it method which accept somthing and return it back
  3. Concerns on controllers, like the example I have given

I would like to have thoughts on this, what is best approach out of it? is it something which can be standarise or it is more situational or I don't know yet :)

Note: - I was looking at this question but answer given on this question is no more valid as referenced links are not working. Right Way to Use Module

Upvotes: 0

Views: 163

Answers (1)

tadman
tadman

Reputation: 211610

The difference here is practically academic, as if you have attr_reader :x then both @x and x will have the same meaning.

It's understood that within a mixin module you will be referencing methods and/or variables that are part of the class or module doing the "mixing in". As such, seeing @x, or in your case, @items, should not come as a real surprise.

If you want to add it as an explicit argument you're sort of missing a lot of the benefits of using a mixin in the first place. You don't need to mix it in at all, you can just use it like B.process_items(...). In other words, your second approach is having an identity crisis. Is it a stand-alone module that includes Concern for no reason, or a weak mixin?

When it comes to testing, you must test the mixin in a module or class which implements the required features. In this case you need either an @items variable, or an items method, and that must have a value of the expected type.

This should be documented somewhere for clarity, but is effectively an implicit contract with anyone using this module.

Upvotes: 3

Related Questions