Mutation bugs are some of the most common in Rubyland.
Why?
Variables are objects and they most likely contain data. This means one or more variables may read data from that variable. If we change the makeup of the object, it could spell disaster for other objects expecting it not to change.
This is prevalent when passing objects via method calls. If a method param gets mutated and passed to another method, the receiving method might not respond properly to the mutated data. The results are less malleable and unreliable code.
One reason to mutate an object is if you're crafting data.
class ApplicationHelper
def admin_body_classes
classes = []
classes << "admin" if admin?
classes << params[:controller]
classes << "environment" if Rails.env.test?
classes.concat(@extra_body_classes) if @extra_body_classes
classes.join(" ").tr("/_", "-")
end
end
In the above example, mutation makes sense. We're returning a data object at the end of admin_body_classes
.
It would not make sense to use a non-mutating operand to classes
. Array#concat
or a shovel operand are suitable for this case since classes
is being mutated throughout the method.
Being mindful of object mutation saves headaches when dealing with objects.
Top comments (0)