Skip to content

Instantly share code, notes, and snippets.

@bbwharris
Created December 16, 2011 05:09
Show Gist options
  • Save bbwharris/1484583 to your computer and use it in GitHub Desktop.
Save bbwharris/1484583 to your computer and use it in GitHub Desktop.
Inject vs. Readability
# There is more than one way to skin a cat, different coders prefer different methods.
include ActionView::Helpers
class Link < Struct.new(:title, :url); end
a = Link.new("Google", "http://www.google.com")
b = Link.new("Hacker News", "http://news.ycombinator.com")
array_of_links = [a, b]
module EnumerableExamples
class << self
# this is elegant and neat, but a headache to understand for newcomers
def the_cool_way(array_of_links)
array_of_links.inject(""){ |output, link| output << link_to(link.title,link.url) }
end
# Another snobby way
def the_each_with_object_way(array_of_links)
array_of_links.each_with_object(""){ |link, output| output << link_to(link.title, link.url) }
end
# This is uncool procedural code, but almost anyone with programming experience
# can understand it.
def the_uncool_way(array_of_links)
output = ""
array_of_links.each do |link|
output << link_to(link.title, link.url)
end
# An explicit return? First of all, ew...
return output
end
#This is what happens when you see the above code and remember #tap before #inject
def the_tap_that_shit_way(array_of_links)
"".tap do |output|
array_of_links.each do |link|
output << link_to(link.title, link.url)
end
end
end
#This is what I want to call the simple obvious solution
def the_map_collect_way(array_of_links)
array_of_links.map{ |link| link_to(link.title, link.url) }.join()
end
end
end
# And the test
EnumerableExamples.methods(false).map{|method| EnumerableExamples.send(method, array_of_links)}.uniq.length == 1
@kennon
Copy link

kennon commented Dec 16, 2011

# This is the way I usually do it. I think it's more understandable and separates
# the string concatenation part from the link generation part

array_of_links.collect {|link| link_to(link.title, link.url)}.join ', '

@moxiesoft
Copy link

I'm with kennon, though I use map instead of collect. For some reason 'map' makes more sense to me than 'collect'.

array_of_links.map { |link| link_to(link.title, link.url) }.join()

@bbwharris
Copy link
Author

This was a bit contrived. I would use collect in this exact example. But it is interesting, to accomplish the same task I have 5 solutions now from different people.

@kennon
Copy link

kennon commented Dec 16, 2011

Personally I use map if I'm performing an action where I'm not necessarily interested in the individual outcome (such as users.map(&:destroy), and collect if I am interested in the outcome. Obviously just a style preference but I try to use semantic conventions like that so my code is faster to parse when I come back to it a few years later :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment