R
Robert Klemme
2008/2/22 said:Often it can make sense to factor the ||= portion into a separate
method:
def category_for(tag)
@categories[tag] ||= []
end
# ...
category_for(resource.tag) << resource
What's the real-world application of this?
There are two reasons to do it:
1. If you're doing this in non-trivial code, you're likely to end up
with multiple @categories[something] ||= [] scattered around; it
only makes sense to factor them into a single method at that point.
This is an advantage for maintainability.
2. "category_for" has a more direct meaning in the problem domain:
category_for(tag) will simply give you the category array for a
particular tag, without needing to expose on the spot the details
of how that category array is obtained. This is an advantage for
readability.
Also, regarding maintainability again, let's say that you decide to
start using objects of class Category instead of arrays; assuming
there is a Category#<< for adding a resource to a category, you can
simply change this:
def category_for(tag)
@categories[tag] ||= []
end
to this:
def category_for(tag)
@categories[tag] ||= Category.new
end
It's the DRY principle: Don't Repeat Yourself.
If there is repetition in your code, it is harder to read (because
you have to mentally filter out the repeated parts to see the
differences -- which are the important part), and you make more work
for yourself (because you must then edit many different places to
effect a single change, and are more likely to make mistakes).
But all these points you mention do also apply to the Hash based
approach. You can even use the same wording, if you like:
@category_for = Hash.new {|h, tag| h[tag] = []}
I was expecting reasoning that would highlight advantages of using a
method here. The only thing that comes to mind is that if you want to
exchange the implementation altogether, then a method based approach
is better. But in that case you'd probably do
def add_to_category(tag, item)
(@cat[tag] ||= []) << item
end
Because that abstracts away category creation *and* adding to the
structure. On the flipside, for small scripts that Hash based
approach has the advantage of being shorter (because no method is
needed).
Kind regards
robert