<?xml version="1.0" encoding="UTF-8"?>
<code>
  <code># stats is an array

@popular_urls = stats.group_by{|s| s.request_uri}.sort_by {|s| s.second.size}.reverse
@referrers = stats.group_by{|s| s.referrer}.sort_by {|s| s.second.size}.reverse
@ip_addresses = stats.reject{|s| s.remote_ip.blank?}.group_by{|s| s.remote_ip}.sort_by {|s| s.second.size}.reverse
@searches = Search.all.group_by{|s| s.query}.sort_by {|s| s.second.size}.reverse # FIXME go through site.searches association
</code>
  <comment>Hello. This is from my blogging app. I'd like to extract a private method that would call group_by for an array of items passed to it, and take a method argument for what to group the records by. At least the first two code lines are exactly the same. I tried using eval() but was unsuccessful at passing a method argument in to be used within the group_by block. any help?</comment>
  <created-at type="datetime">2009-06-12T15:28:06+00:00</created-at>
  <id type="integer">915</id>
  <language>Ruby</language>
  <permalink>extract-method</permalink>
  <refactors-count type="integer">2</refactors-count>
  <title>Extract method</title>
  <trackback-url></trackback-url>
  <updated-at type="datetime">2009-06-24T00:02:17+00:00</updated-at>
  <user-id type="integer">1548</user-id>
  <refactors type="array">
    <refactor>
      <code># You can factor out the common aspects:

module Popularity
  def rank_by
    group_by {|e| yield e }.sort_by {|e| -e.second.size }
  end
end

# Then the question is, how intrusive do you want it to be?  You can use it 
# as you need it:

stats.extend Popularity
@popular_urls = stats.rank_by {|s| s.request_uri }
@referrers    = stats.rank_by {|s| s.referrer }

@ip_addresses = stats.reject {|s| s.remote_ip.blank? }.extend(Popularity).rank_by {|s| s.remote_ip }

@searches = Search.all.extend(Popularity).rank_by {|s| s.query }

# Or if you use the pattern regularly, you can make it available (almost?) 
# everywhere, at the expense of monkey-patching Array.

class Array; include Popularity; end

@popular_urls = stats.rank_by {|s| s.request_uri }
@referrers    = stats.rank_by {|s| s.referrer }
@ip_addresses = stats.reject {|s| s.remote_ip.blank? }.rank_by {|s| s.remote_ip }
@searches     = Search.all.rank_by {|s| s.query } # Untested - not sure if AR proxies get all Array methods
</code>
      <code-id type="integer">915</code-id>
      <comment></comment>
      <created-at type="datetime">2009-06-14T16:42:27+00:00</created-at>
      <id type="integer">163513</id>
      <language>Ruby</language>
      <rating type="integer">0</rating>
      <ratings-count type="integer">0</ratings-count>
      <title>On Extract method</title>
      <user-id type="integer" nil="true"></user-id>
      <user-name>mainej</user-name>
      <user-website></user-website>
    </refactor>
    <refactor>
      <code></code>
      <code-id type="integer">915</code-id>
      <comment>Awesome, I made a module following your approach, thanks for your time.</comment>
      <created-at type="datetime">2009-06-24T00:02:16+00:00</created-at>
      <id type="integer">168529</id>
      <language>Ruby</language>
      <rating type="integer">0</rating>
      <ratings-count type="integer">0</ratings-count>
      <title>On Extract method</title>
      <user-id type="integer">1548</user-id>
      <user-name>webandy.myopenid.com</user-name>
      <user-website nil="true"></user-website>
    </refactor>
  </refactors>
</code>
