Hi,
James Gray's refactoring of my decidedly anidiomatic solution to Quiz
#43 has caused me to add a note to my "Ruby Way journal" that basically
says, "don't use Array indices if you can avoid it". My C++/Python
experience leads me reflexively to indices even when iteratiors and
append methods like << provide a more elegant solution.
Today I met a coding problem that made me start to reach for indices,
and since the above note is recent in my journal, I stopped to think how
it might be done without them. Nothing's coming to mind so I thought
I'd post here and see if there's yet another Ruby Epiphany waiting to
happen to me. :-)
I want to print a list of items and the output of a transform on those
items. E.g. each element should be something like "#{x}: #{f(x)}". The
transform is applied to the entire array at once, however, and returns
an entire array, I can't just iterate on the array applying f(x) to each
element. (The transform normalizes an array, returning an array of
ratios of item / (sum of all items).)
My original thought was to simply say:
normalized_values = values.normalize
...but now values and normalized_values are two arrays that are
implicitly related by index. Better, I think, somehow to relate them
explicitly.
Normalize is a method I have added to Array. One way to explicitly
relate the methods would be to add an iterator method to Array:
class Array
def each_normal
normals = self.normalize
normals.each do |n|
yield n
end
end
end
...but that still doesn't feel right. each_normal makes me think that I
have a subclass struggling to get out here: I want to add a method
"normal(n)" that returns the normal of item at index n, and doing that
means that the Array really should be subclassed so it can cache a
@total value for performance reasons. Array probably *should* be
subclassed anyway, since normalize really only applies to Arrays of
things that can be summed and divided.
But I've already started another thread about that. Right now, I'm just
thinking that when you find yourself walking two arrays in parallel,
that seems to me to be a code smell.
What's the cleanup? Zipping the two arrays together would even be a
better solution, I think, thought it makes for uglier code like
"#{pair[0]}: #{pair[1]}".
Thoughts?
-dB
--
David Brady
ruby_talk / shinybit.com
I'm feeling really surreal today... OR AM I?