<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dr Nic &#187; map_by_method</title>
	<atom:link href="http://drnicwilliams.com/category/ruby/gems/map_by_method/feed/" rel="self" type="application/rss+xml" />
	<link>http://drnicwilliams.com</link>
	<description>Ruby makes Rails, Javascript makes Ajax, Dr Nic makes Magic</description>
	<lastBuildDate>Tue, 03 Aug 2010 23:44:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>map_by_method &#8211; the final announcement</title>
		<link>http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/</link>
		<comments>http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 09:42:36 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[map_by_method]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/</guid>
		<description><![CDATA[I don&#8217;t really talk about my projects after I release them except to show off fancy new things, like newgem sporting the new RubiGen generator. So I don&#8217;t know why I give updates here about one of the smallest projects &#8211; map_by_method. Probably, its because it doesn&#8217;t deserve a Google Group or even a webpage [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/29/myconfplan-sale-less-than-12-hours-to-go/' rel='bookmark' title='Permanent Link: MyConfPlan sale &#8211; less than 12 hours to go'>MyConfPlan sale &#8211; less than 12 hours to go</a> <small>The auction for MyConfPlan has less than 12 hours to...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/04/15/welcome-to-the-future/' rel='bookmark' title='Permanent Link: Welcome to the future'>Welcome to the future</a> <small>Welcome to anyone visiting from DHH&#8217;s blog and other corners...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t really talk about my projects after I release them except to show off fancy new things, like <a href="http://newgem.rubyforge.org">newgem</a> sporting the new <a href="http://rubigen.rubyforge.org">RubiGen generator</a>.</p>
<p>So I don&#8217;t know why I give updates here about one of the smallest projects &#8211; <code>map_by_method</code>.</p>
<p>Probably, its because it doesn&#8217;t deserve a Google Group or even a webpage really. It should probably be integrated into activesupport gem or something.</p>
<p>Except, it just never seemed to 100% work.</p>
<p>That is, it go more blog coverage than anything else, but wasn&#8217;t always useful. Yeah, a like Miss South Carolina.</p>
<p><strong>BUT Version 0.8.2 is now out. It fixes &#8211; I believe &#8211; all known problems &#8211; I think.</strong></p>
<pre>gem install map_by_method
</pre>
<p>In your code (or config/environment.rb for rails):</p>
<pre>gem 'map_by_method', '&gt;=0.8.2'
require 'map_by_method'
</pre>
<p>I added a few more iterator methods too: <code>sort_by</code>, <code>group_by</code>, and <code>index_by</code>.</p>
<pre>&gt;&gt; Conference.find(1).conference_sessions.group_by_from
=&gt; returns all MyConfPlan conference sessions grouped by start time, for RailsConf2007
</pre>
<h2 id="myconfplan8230">MyConfPlan&#8230;</h2>
<p>Oh yes it sold. Announcement coming soon.</p>
<p>Plus, a link to the code &#8211; as it is being open sourced by its new owner. Sweet!</p>
<p>Well&#8230; sweet for you. I already had access to the code.</p>
<h2 id="next_on_the_todo_list">Next on the todo list</h2>
<p>Add something similar to <a href="http://errtheblog.com/post/10722" title="err.the_blog.find_by_title('Full of Ambition')">Ambition</a> by Err &#8220;we-write-so-many-cool-projects-I-don&#8217;t-know-how-we-find-time-to-maintain-them-all&#8221; the Blog, Chris and PJ.</p>
<p>I&#8217;d kind link something like: </p>
<pre>Conference.select { |c| c =~ "Rails").sort_by_name
</pre>
<p>Which would behave like:</p>
<pre>&gt;&gt; Conference.select {|c| c.name =~ /Rails/}.sort_by(&amp;:name).to_sql
=&gt; "SELECT * FROM conferences WHERE conferences.\"name\" ~ 'Rails' ORDER BY conferences.name"
</pre>
<p>Oh well, perhaps we can talk about it during RailsConf Europe, when I get the microphone to talk about such tom-foolery and hi-jinx: <a href="http://www.railsconfeurope.com/cs/railseurope2007/view/e_sess/14243" title="RailsConf Europe 2007 &#8226; September 17, 2007 - September 19, 2007 &#8226; Berlin, Germany">Meta-Magic in Rails: Become a Master Magician</a></p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/29/myconfplan-sale-less-than-12-hours-to-go/' rel='bookmark' title='Permanent Link: MyConfPlan sale &#8211; less than 12 hours to go'>MyConfPlan sale &#8211; less than 12 hours to go</a> <small>The auction for MyConfPlan has less than 12 hours to...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/04/15/welcome-to-the-future/' rel='bookmark' title='Permanent Link: Welcome to the future'>Welcome to the future</a> <small>Welcome to anyone visiting from DHH&#8217;s blog and other corners...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>map_by_method now works with ActiveRecord associations</title>
		<link>http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/</link>
		<comments>http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/#comments</comments>
		<pubDate>Sun, 12 Aug 2007 07:31:58 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Trick]]></category>
		<category><![CDATA[map_by_method]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/</guid>
		<description><![CDATA[I was always annoyed that map_by_method was broken for ActiveRecord has_many associations. 6 mths later I finally fixed it. That&#8217;s the magic of Open Source Software. [/end sarcasm] So now, the following example works like it should: $ gem install map_by_method $ console &#62; require 'map_by_method' # stick this in your environment.rb for Rails &#62; [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2008/01/01/find-objects-in-irb-directly-from-browser-urls/' rel='bookmark' title='Permanent Link: Find objects in IRB directly from browser URLs'>Find objects in IRB directly from browser URLs</a> <small>A long time ago, I tired of going into the...</small></li><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/magiccgi/' rel='bookmark' title='Permanent Link: MagicCGI shows OpenID user count'>MagicCGI shows OpenID user count</a> <small> In the last 20 days, 43 people have used...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I was always annoyed that <a href="http://drnicutilities.rubyforge.org/map_by_method"><code>map_by_method</code></a> was broken for ActiveRecord <code>has_many</code> associations. 6 mths later I finally fixed it.</p>
<p>That&#8217;s the magic of Open Source Software. [/end sarcasm]</p>
<p>So now, the following example works like it should:</p>
<pre>$ gem install map_by_method
$ console
&gt; require 'map_by_method'  # stick this in your environment.rb for Rails
&gt; user = User.find_by_name "Dr Nic"
&gt; user.companies.map_by_name
=&gt; ['Dr Nic Academy', 'Dr Nic Institute of Being Silly']
&gt; user.companies.map_by_id_and_name
=&gt; [[1, 'Dr Nic Academy'], [9, 'Dr Nic Institute of Being Silly']]
</pre>
<h2 id="recap_why_use_map_by_method">Recap: why use <code>map_by_method</code>?</h2>
<p>Try the following example:</p>
<pre>&gt; user.companies.map_by_employees.flatten
=&gt; list of all employees of user
</pre>
<p>Versus:</p>
<pre>&gt; user.companies.map { |company| company.employees}.flatten
or
&gt; user.companies.map(&amp;:employees).flatten
</pre>
<p>Or compare:</p>
<pre>&gt; user.companies.map_by_id_and_name
=&gt; [[1, 'Dr Nic Academy'], [9, 'Dr Nic Institute of Being Silly']]
</pre>
<p>Versus:</p>
<pre>&gt; user.companies.map { |company| [company.id, company.name]}
</pre>
<p>That is, it looks and feels just like ActiveRecord&#8217;s #find method, with its <code>find_by_first_name_and_last_name</code> magic.</p>
<h2 id="summary">Summary</h2>
<p>No <code>{</code>, <code>}</code>, <code>|</code>, <code>&amp;</code>, or <code>:</code> required. Just clean method names.</p>
<h1 id="bonus_other_gem">Bonus other gem</h1>
<p>In the spirit of ActiveRecord hacks, there is <code>to_activerecord</code>:</p>
<pre>$ gem install to_activerecord
$ console
&gt; require 'to_activerecord'  # stick this in your environment.rb for Rails
&gt; [1,2,3].to_user
=&gt; [list of User with id's 1,2,3]
</pre>
<p>To me, this suffix operator reads cleaner than the traditional:</p>
<pre>&gt; User.find([1,2,3])
</pre>
<p>For example, if you want to perform an operation on the list of Users:</p>
<pre>&gt; ids = [1,2,3]
&gt; ids.to_user.map_by_name
=&gt; ['Dr Nic', 'Banjo', 'Nancy']
</pre>
<p>Versus:</p>
<pre>&gt; User.find(ids).map_by_name
</pre>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2008/01/01/find-objects-in-irb-directly-from-browser-urls/' rel='bookmark' title='Permanent Link: Find objects in IRB directly from browser URLs'>Find objects in IRB directly from browser URLs</a> <small>A long time ago, I tired of going into the...</small></li><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/magiccgi/' rel='bookmark' title='Permanent Link: MagicCGI shows OpenID user count'>MagicCGI shows OpenID user count</a> <small> In the last 20 days, 43 people have used...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>map_by_method now increasingly more niftier-er.</title>
		<link>http://drnicwilliams.com/2006/10/26/map_by_method-now-increasingly-more-niftier-er/</link>
		<comments>http://drnicwilliams.com/2006/10/26/map_by_method-now-increasingly-more-niftier-er/#comments</comments>
		<pubDate>Thu, 26 Oct 2006 12:05:44 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[map_by_method]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/10/26/map_by_method-now-increasingly-more-niftier-er/</guid>
		<description><![CDATA[Recap on map_by_method magic: >> p.account.transfers.map_amount # amount method mapped to all Transfers => [1878.35, 433.0, 433.0, 433.46, 433.46, 433.46, 433.46, 433.46, 300.0, 300.0] >> p.account.transfers.map_date.map_to_s # date method mapped to all Transfers, and the Dates mapped into strings => ["2003-05-27", "2003-06-23", "2003-06-27", "2003-07-04", "2003-07-11", "2003-07-18", "2003-07-25", "2003-08-08", "2003-09-25", "2003-10-03"] But if you want the [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/04/15/welcome-to-the-future/' rel='bookmark' title='Permanent Link: Welcome to the future'>Welcome to the future</a> <small>Welcome to anyone visiting from DHH&#8217;s blog and other corners...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Recap on <a href="http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/">map_by_method</a> <a href="http://drnicwilliams.com/2006/10/04/i-love-map-by-pluralisation/">magic</a>:</p>
<pre>
>> p.account.transfers.<span class=constant>map_amount</span> <span class=comments># amount method mapped to all Transfers</span>
=> [1878.35, 433.0, 433.0, 433.46, 433.46, 433.46, 433.46, 433.46, 300.0, 300.0]
>> p.account.transfers.<span class=constant>map_date</span>.<span class=constant>map_to_s</span> <span class=comments># date method mapped to all Transfers, and the Dates mapped into strings</span>
=> ["2003-05-27", "2003-06-23", "2003-06-27", "2003-07-04", "2003-07-11", "2003-07-18", "2003-07-25", "2003-08-08", "2003-09-25", "2003-10-03"]
</pre>
<p>But if you want the <code>amount</code> and <code>date</code> methods mapped at the same you&#8217;ve been plain out of luck, and forced to use the uglier block syntax:</p>
<pre>
>> p.account.transfers.map {|t| [t.amount, t.date]}
</pre>
<p>Due to demand-by-inspiration (that is, I just thought of it), you can now use <code>_and_</code> to join method names together, thusly:</p>
<pre>
>> p.account.transfers.<span class=constant>map_date_and_amount</span>
[[#&lt;Date: 4905573/2,0,2299161>, 1878.35],
 [#&lt;Date: 4905627/2,0,2299161>, 433.0],
 [#&lt;Date: 4905635/2,0,2299161>, 433.0],
 [#&lt;Date: 4905649/2,0,2299161>, 433.46],
 [#&lt;Date: 4905663/2,0,2299161>, 433.46],
 [#&lt;Date: 4905677/2,0,2299161>, 433.46],
 [#&lt;Date: 4905691/2,0,2299161>, 433.46],
 [#&lt;Date: 4905719/2,0,2299161>, 433.46],
 [#&lt;Date: 4905815/2,0,2299161>, 300.0],
 [#&lt;Date: 4905831/2,0,2299161>, 300.0]]
>> p.account.transfers.<span class=constant>map_date_and_amount</span>.<span class=constant>map_map_to_s</span>
[["2003-05-27", "1878.35"],
 ["2003-06-23", "433.0"],
 ["2003-06-27", "433.0"],
 ["2003-07-04", "433.46"],
 ["2003-07-11", "433.46"],
 ["2003-07-18", "433.46"],
 ["2003-07-25", "433.46"],
 ["2003-08-08", "433.46"],
 ["2003-09-25", "300.0"],
 ["2003-10-03", "300.0"]]
</pre>
<p>Note the dubious/amusing use of <code>map_map_to_s</code> to apply <code>to_s</code> to the inner arrays. That is, <code>map_to_s</code> is mapped to each inner array.</p>
<p>Want this extended <strong>map_by_method</strong> magic? Version 0.5 of <strong>map_by_method</strong> is ready via <code>gem install map_by_method</code> now (or <a href="http://rubyforge.org/frs/?group_id=2351&#038;release_id=7589">direct download</a>)</p>
<h3>Bonus use</h3>
<p>Make simple arrays for drop-down lists based on id and a string name field of a list of objects.</p>
<pre>
>> User.find(:all).map_id_and_firstname
=> [[1, "Glenda"], [2, "Brenda"], [3, "Yas"], [4, "Osborne"], [5, "Gary"], [6, "Anthony"], [7, "Jackie"]]
</pre>
<h3>Debugging use</h3>
<p>Some of my Transfer rows had amounts of zero. This was just stupid, but as the initial data was being migrated from a variety of sources I needed to figure out where it was coming from.</p>
<p>&#8220;I wonder which account owner(s) this erroneous data comes from?&#8221;</p>
<pre>
> zero_transfers = Transfer.find(:all,:conditions => ['amount < 10 and amount > -10'])
> zero_transfers.<span class=constant>map_from_account.map_owner.map_name</span>
["Brenda",
"Brenda",
"Brenda",
"Brenda",
"Brenda"]
</pre>
<p>And I now knew which files to start cleaning up before re-importing all the data again.</p>
<p>Data investigation in the console/irb becomes almost fun.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/04/15/welcome-to-the-future/' rel='bookmark' title='Permanent Link: Welcome to the future'>Welcome to the future</a> <small>Welcome to anyone visiting from DHH&#8217;s blog and other corners...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/10/26/map_by_method-now-increasingly-more-niftier-er/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>My .irbrc for console/irb</title>
		<link>http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/</link>
		<comments>http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/#comments</comments>
		<pubDate>Thu, 12 Oct 2006 11:06:33 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Link]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[map_by_method]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/</guid>
		<description><![CDATA[The relatively unspoken warhorse of Ruby/Rails programming is the irb/console [1]. Ruby is such a joy to work with in part from this one development tool. I got tired of typing require 'pp' and the like each time I loaded up my console, that I was joyed to discover I could configure it: using the [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/04/12/magic-multi-connections-a-facility-in-rails-to-talk-to-more-than-one-database-at-a-time/' rel='bookmark' title='Permanent Link: Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;'>Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;</a> <small>At this point in time there’s no facility in Rails...</small></li><li><a href='http://drnicwilliams.com/2006/10/11/generating-new-gems/' rel='bookmark' title='Permanent Link: [ANN] Generating new gems for graceful goodliness'>[ANN] Generating new gems for graceful goodliness</a> <small> I don&#8217;t like you [1]. You don&#8217;t share code....</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://errtheblog.com/post/26">relatively</a> unspoken warhorse of Ruby/Rails programming is the <strong>irb/console</strong> [<a href="#irbrc1">1</a>]. Ruby is such a joy to work with in part from this one development tool.</p>
<p>I got tired of typing <code>require 'pp'</code> and the like each time I loaded up my console, that I was joyed to discover I could configure it: using the <code>.irbrc</code> file (win32 explanation <a href="#irbrc_win32">below</a>).</p>
<p>Here is mine:</p>
<pre>
require '<span class=string>irb/completion</span>'
require '<span class=string>map_by_method</span>'
require '<span class=string>what_methods</span>'
require '<span class=string>pp</span>'
IRB.conf[:AUTO_INDENT]=true
</pre>
<p>Here is what each line does:</p>
<h2>Line 1 &#8211; Auto-completion in IRB</h2>
<p>You can discover what methods can be called on an object. <strong>Double-TAB</strong> is your &#8220;exploration&#8221; combo.</p>
<pre>
irb(main):001:0> "hello".to_<span class=constant>&lt;double TAB here&gt;</span>
.to_a    .to_f    .to_i    .to_s    .to_str  .to_sym
irb(main):003:0> a = "hello"
=> "test"
irb(main):004:0> a.t<span class=constant>&lt;double TAB here&gt;</span>
a.taint     a.to_f      a.to_str    a.tr!       a.type
a.tainted?  a.to_i      a.to_sym    a.tr_s
a.to_a      a.to_s      a.tr        a.tr_s!</pre>
<p>Not understanding this? <a href="http://showmedo.com/videos/video?name=rubyLakeIrbCompletion">Watch the video</a></p>
<h2>Line 2 &#8211; Map by Method</h2>
<p>When in the console its great to be able to explore and manipulate data as quickly as possible. The Map by Method (previously called Map by Pluralisation) is wizardly for quick-to-type array manipulations.</p>
<p>See the <a href="http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/">original</a> and <a href="http://drnicwilliams.com/2006/10/04/i-love-map-by-pluralisation/">demo</a> articles.</p>
<p>To install:</p>
<pre>
gem install <span class=string>map_by_method</span>
</pre>
<h2>Line 3 &#8211; MethodFinder/Object.what?</h2>
<p>Ever asked: &#8220;if I have an object, what method can I call on it to get that result?&#8221;</p>
<p>See if this suits your console cravings:</p>
<pre>
> 3.45.<span class=constant>what?</span> 3
3.45.truncate == 3
3.45.to_i == 3
3.45.prec_i == 3
3.45.floor == 3
3.45.to_int == 3
3.45.round == 3
=> ["truncate", "to_i", "prec_i", "floor", "to_int", "round"]
> 3.45.<span class=constant>what?</span> 4
3.45.ceil == 4
=> ["ceil"]
> 3.55.<span class=constant>what?</span> 4
3.55.ceil == 4
3.55.round == 4
=> ["ceil", "round"]
</pre>
<p>Just what you need in the console.</p>
<p>I&#8217;ve gemified a library found on <a href="http://redhanded.hobix.com/inspect/stickItInYourIrbrcMethodfinder.html">_why&#8217;s blog</a> by Nikolas Coukouma.</p>
<p>To install:</p>
<pre>
gem install <span class=string>what_methods</span>
</pre>
<h2>Line 4 &#8211; pretty print</h2>
<p>pp = pretty print &#8211; wondeful in the console for exploring objects that are visually large.</p>
<p>Thusly demonstrated:</p>
<pre>
> me = {<span class=symbol>:name</span> => "Nic Williams", <span class=symbol>:country</span> => "Netherlands", <span class=symbol>:city</span> => "Amsterdam", <span class=symbol>:tags</span> => %w(ruby rails javascript)}
=> {<span class=symbol>:country</span>=>"Netherlands", <span class=symbol>:name</span>=>"Nic Williams", <span class=symbol>:city</span>=>"Amsterdam", <span class=symbol>:tags</span>=>["ruby", "rails", "javascript"]}
irb(main):017:0> <span class=constant>pp</span> me
{<span class=symbol>:country</span>=>"Netherlands",
 <span class=symbol>:name</span>=>"Nic Williams",
 <span class=symbol>:city</span>=>"Amsterdam",
 <span class=symbol>:tags</span>=>["ruby", "rails", "javascript"]}
=> nil
</pre>
<p>It prints, and its pretty.</p>
<h2>Line 5 &#8211; auto-tabbing turned on</h2>
<p>Auto-tabbing is the console&#8217;s way of trying to help your code look pretty by indenting your blocks, etc.</p>
<p>It&#8217;s only primitive, but better than a kick in the teeth.</p>
<pre>
> [1,2,3].each do |a|
*     puts a
>   end
1
2
3
=> [1, 2, 3]
</pre>
<h2 id="irbrc_win32">.irbrc for Win32</h2>
<p>Create a file called anything you like (e.g. &#8220;_irbrc&#8221; or &#8220;irb.rc&#8221;) and place it anywhere you like (say C:\Documents and Settings\<username>), and set that full path to the ENV variable <code>IRBRC</code>, e.g. <code>C:\Documents and Settings\<username>\_irbrc</code></p>
<p>More ideas at the bottom of <a href="http://www.gatago.com/comp/lang/ruby/11562567.html">this</a>.</p>
<h2>Epilogue</h2>
<p>Any other useful libraries to include in irb/console?</p>
<p><a name="irbrc1">[1]</a> You can run <code>irb</code> from anywhere, but to use <code>console</code> for a specific rails app, you need to point to the console script for that app, e.g <code>ruby script/console</code> from the rails app root folder.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/04/12/magic-multi-connections-a-facility-in-rails-to-talk-to-more-than-one-database-at-a-time/' rel='bookmark' title='Permanent Link: Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;'>Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;</a> <small>At this point in time there’s no facility in Rails...</small></li><li><a href='http://drnicwilliams.com/2006/10/11/generating-new-gems/' rel='bookmark' title='Permanent Link: [ANN] Generating new gems for graceful goodliness'>[ANN] Generating new gems for graceful goodliness</a> <small> I don&#8217;t like you [1]. You don&#8217;t share code....</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/10/12/my-irbrc-for-consoleirb/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>[ANN] Generating new gems for graceful goodliness</title>
		<link>http://drnicwilliams.com/2006/10/11/generating-new-gems/</link>
		<comments>http://drnicwilliams.com/2006/10/11/generating-new-gems/#comments</comments>
		<pubDate>Wed, 11 Oct 2006 07:23:47 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Gems]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[map_by_method]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/10/11/generating-new-gems/</guid>
		<description><![CDATA[I don&#8217;t like you [1]. You don&#8217;t share code. I know, I know, you&#8217;ve had good reasons &#8211; you don&#8217;t know how to create a Ruby gem, how to upload it to a gem server like RubyForge, and you&#8217;re a chicken. Today we&#8217;ll remove the first of these minor roadblocks, with a New Gem Generator! [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2008/12/05/my-rubygems-development-tools-and-workflow/' rel='bookmark' title='Permanent Link: My RubyGems development tools and workflow'>My RubyGems development tools and workflow</a> <small> The Open Source Developers Conference (osdc) is a nifty...</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<div style="float: right;"><img src="http://drnicwilliams.com/wp-content/uploads/2006/10/chicken.jpg" alt="Chicken!" /></div>
<p>I don&#8217;t like you [<a href="#newgem1">1</a>]. You don&#8217;t share code. I know, I know, you&#8217;ve had good reasons &#8211; you don&#8217;t know how to create a Ruby gem, how to upload it to a gem server like RubyForge, and you&#8217;re a chicken. Today we&#8217;ll remove the first of these minor roadblocks, with a New Gem Generator!</p>
<p>Now you can take any <em>library</em> or <em>Rails plugin</em> or <em>command line application</em>, gemify it, and easily share it with the Ruby world. With gems you get in-built version support (you can specify which version of a gem you want when you use it via the <a href="http://rubygems.org/read/chapter/4#page71">require_gem</a> method), an encapsulated, consistent folder structure for your bin/lib/test folders, and you get cross-platform support for bin apps. Too much niftiness to ignore, really.</p>
<p>The New Gem Generator is like the <code>rails</code> command for rails applications, but it creates the folders and starting files for a new gem. It&#8217;s called <code>newgem</code>.</p>
<h2>Tutorial</h2>
<h3>Aim</h3>
<p>To convert the <strong>Map by Method</strong> (previously called Map by Pluralisation) library into a gem.</p>
<p>See <a href="http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/">original</a> and <a href="http://drnicwilliams.com/2006/10/04/i-love-map-by-pluralisation/">demo</a> articles. Sex on a stick &#8211; soon to be gemified before your very eyes. (<a href="#newgem_remote">Download instructions</a> for the prebuilt gem)</p>
<h3>Installation</h3>
<pre>
> gem install <span class=constant>newgem</span>
</pre>
<p>Download from <a href="http://rubyforge.org/frs/?group_id=2340&#038;release_id=7337">rubyforge</a> if you have firewall problems (as I do at work) and need to get the gem explicitly first. THEN run the above command in the folder you saved the gem.</p>
<h3>Create new gem</h3>
<pre>
> <span class=constant>newgem map_by_method</span>
creating: map_by_method
creating: map_by_method/CHANGELOG
creating: map_by_method/README
creating: map_by_method/lib
creating: map_by_method/lib/map_by_method
creating: map_by_method/lib/map_by_method.rb
creating: map_by_method/lib/map_by_method/version.rb
creating: map_by_method/Rakefile
creating: map_by_method/test
creating: map_by_method/test/all_tests.rb
creating: map_by_method/test/test_helper.rb
creating: map_by_method/test/map_by_method_test.rb
creating: map_by_method/examples
creating: map_by_method/bin
</pre>
<h3>Copy in the library</h3>
<p>The generated <code>lib/map_by_method.rb</code> file looks like:</p>
<pre>
Dir['map_by_method/**/*.rb'].sort.each { |lib| require lib }
</pre>
<p>This will automatically include (<code>require</code>), in alphabetical order, the files in the<br />
<code>lib/map_by_method</code> folder. If you need the files required in a specific order, then do it explicitly here, for example:</p>
<pre>
require 'foo'
require 'bar'
require 'tar'
</pre>
<p>or</p>
<pre>
%w(foo bar tar).each {|lib| require lib}
</pre>
<p>For this gem there won&#8217;t be any additional library files, so we&#8217;ll just copy in the following code into the <code>lib/map_by_method.rb</code> file and remove the library loading code.</p>
<pre>
module <span class=constant>MapByMethod</span>
  def self.included(base)
    super

    base.module_eval <<-EOS
      def method_missing(method, *args, &#038;block)
        super
      rescue NoMethodError
        error = $!
        begin
          re = /(map|collect|select|each|reject)_([\\w\\_]+\\??)/
          if (match = method.to_s.match(re))
            iterator, callmethod = match[1..2]
            return self.send(iterator) {|item| item.send callmethod}
          end
          return self.map {|item| item.send method.to_s.singularize.to_sym}
        rescue NoMethodError
          nil
        end
        raise error
      end
    EOS
  end
end

unless String.instance_methods.include? "singularize"
  class String
    def singularize
      self.gsub(/e?s\Z/,'')
    end
  end
end

<span class=constant>Array</span>.send :include, <span class=constant>MapByMethod</span>
</pre>
<h3>Package your gem into a .gem file</h3>
<p>From the root folder of your gem run <code>rake package</code>:</p>
<pre>
> rake <span class=constant>package</span>
(in C:/InstantRails/ruby_apps/map_by_method)
rm -r .config
  Successfully built RubyGem
  Name: map_by_method
  Version: 0.0.1
  File: map_by_method-0.0.1.gem
mv map_by_method-0.0.1.gem pkg/map_by_method-0.0.1.gem
</pre>
<p>Tada! You are the owner of a gem.</p>
<h3>Install your gem onto your machine</h3>
<p>Your Ruby (and Rails) applications can only use the gemified libraries once you have installed the packaged gem. This is the same for other people who will use your gem.</p>
<p>Typically you install a gem from a remote gem server such as rubyforge. Today, you will install the gem locally:</p>
<pre>
> gem install <span class=constant>pkg/map_by_method-0.0.1.gem</span>
Attempting local installation of 'pkg/map_by_method-0.0.1.gem'
Successfully installed map_by_method, version 0.0.1
Installing RDoc documentation for map_by_method-0.0.1...
</pre>
<p>Note that it created and installed RDoc documentation for the library too. Each user automatically has a copy of the generated documentation for your libraries (if you actually added documentation to your code).</p>
<h3>Unit testing</h3>
<p>Look in the <code>test</code> folder and see that it has created a <code>map_by_method_test.rb</code> unit test file to get you started. Put tests in there. Add more test files. Run <code>rake test</code> from the project&#8217;s root folder and watch all your tests succeed or fail. Be good.</p>
<h3>Version numbers</h3>
<p>Note that the generated gem is <code>map_by_method-0.0.1.gem</code>. The 0.0.1 is the version number of the gem, and you can easily change this as you wish as you gem takes on new features and fixes.</p>
<p>There are two common version number formats:</p>
<p>X.Y.Z &#8211; X = major release number, Y = minor release number, Z = patch/bug fix number</p>
<p>or</p>
<p>X.Y.Z.svn = svn is the subversion number at the time the gem was released.</p>
<p>The latter is the default implementation generated by newgem. If you want the simpler version number format (the 1st one), then remove the following line from your Rakefile (around line 13):</p>
<pre>
REV = File.read(".svn/entries")[/committed-rev="(\d+)"/, 1] rescue nil
</pre>
<p>Your gem has a prebuilt mechanism for specifying the X.Y.Z portion of the version number.</p>
<p>Go to <code>lib/map_by_method/version.rb</code></p>
<pre>
module <span class=constant>MapByMethod</span> <span class=comments>#:nodoc:</span>
  module <span class=constant>VERSION</span> <span class=comments>#:nodoc:</span>
    <span class=constant>MAJOR</span> = 0
    <span class=constant>MINOR</span> = 0
    <span class=constant>TINY</span>  = 1

    <span class=constant>STRING</span> = [MAJOR, MINOR, TINY].join('.')
  end
end
</pre>
<p>Change MINOR and TINY to:</p>
<pre>
    <span class=constant>MINOR</span> = 1
    <span class=constant>TINY</span>  = 0
</pre>
<p>And repackage and reinstall your gem:</p>
<pre>
> rake <span class=constant>package</span>
(in C:/InstantRails/ruby_apps/map_by_method)
rm -r .config
  Successfully built RubyGem
  Name: map_by_method
  Version: 0.1.0
  File: map_by_method-0.1.0.gem
mv map_by_method-0.1.0.gem pkg/map_by_method-0.1.0.gem

> gem install <span class=constant>pkg/map_by_method-0.1.0.gem</span>
Attempting local installation of 'pkg/map_by_method-0.1.0.gem'
Successfully installed map_by_method, version 0.1.0
Installing RDoc documentation for map_by_method-0.1.0...
</pre>
<p>And you&#8217;re done. Next you would upload your gem to a gem server such as RubyForge, or one your company runs internally to share gems via the &#8220;gem install&#8221; mechanism.</p>
<h2 name="newgem_remote">map_by_method already on RubyForge</h2>
<p>If you want the <strong>map_by_method</strong> gem, its already on RubyForge, so you can remotely install it:</p>
<pre>
gem install <span class=constant>map_by_method</span>
</pre>
<h2>Inspiration</h2>
<p><a href="http://jayfields.blogspot.com">Jay Fields</a> created a great &#8220;ruby application setup&#8221; <a href="http://jayfields.blogspot.com/2006/10/ruby-project-tree.html">script</a>.</p>
<p><a name="newgem1">[1]</a> That&#8217;s not true. I do like you. </p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2008/12/05/my-rubygems-development-tools-and-workflow/' rel='bookmark' title='Permanent Link: My RubyGems development tools and workflow'>My RubyGems development tools and workflow</a> <small> The Open Source Developers Conference (osdc) is a nifty...</small></li><li><a href='http://drnicwilliams.com/2008/10/31/newgem-100-all-thanks-to-cucumber/' rel='bookmark' title='Permanent Link: newgem 1.0.0 all thanks to Cucumber'>newgem 1.0.0 all thanks to Cucumber</a> <small>The New Gem Generator (newgem) was exciting, moderately revolutionary, and...</small></li><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/10/11/generating-new-gems/feed/</wfw:commentRss>
		<slash:comments>62</slash:comments>
		</item>
		<item>
		<title>I love &#8220;map by pluralisation&#8221; [now: map_by_method]</title>
		<link>http://drnicwilliams.com/2006/10/04/i-love-map-by-pluralisation/</link>
		<comments>http://drnicwilliams.com/2006/10/04/i-love-map-by-pluralisation/#comments</comments>
		<pubDate>Wed, 04 Oct 2006 14:12:51 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[map_by_method]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/10/04/i-love-map-by-pluralisation/</guid>
		<description><![CDATA[Update: this is a gem called map_by_method. The other day I introduced a new syntax idea that I call &#8220;map by pluralisation&#8221;. Everyday I use it in code and in the console/irb I fall more in love with its simplicity &#8211; both to type and to read. The following are all equivalent: >> BankTransaction.columns.names # [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/03/02/5-things-im-in-love-with/' rel='bookmark' title='Permanent Link: 5 things I&#8217;m in love with'>5 things I&#8217;m in love with</a> <small>In no specific order, but enumerated for good measure: autotest...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Update: this is a gem called <a href="http://drnicwilliams.com/2006/10/11/generating-new-gems/">map_by_method</a>.</p>
<p>The other day I <a href="http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/">introduced a new syntax idea</a> that I call &#8220;map by pluralisation&#8221;. Everyday I use it in code and in the console/irb I fall more in love with its simplicity &#8211; both to type and to read.</p>
<p>The following are all equivalent:</p>
<pre>
>> BankTransaction.columns.<span class=constant>names</span>  <span class=comments># map by pluralisation</span>
=> ["id", "amount", "date", "description", "balance"]
>> BankTransaction.columns.<span class=constant>name</span>   <span class=comments># singular works too</span>
=> ["id", "amount", "date", "description", "balance"]
>> BankTransaction.columns.<span class=constant>map_name</span>  <span class=comments># merge collector (map) + operation (name is method of BankTransaction object)</span>
=> ["id", "amount", "date", "description", "balance"]
>> BankTransaction.columns.<span class=constant>collect_name</span>  <span class=comments># merge collector (collect) + operation</span>
=> ["id", "amount", "date", "description", "balance"]
</pre>
<p>All of which are <strong>easier to read and quicker to type</strong> than the current equivalents:</p>
<pre>
>> BankTransaction.columns.<span class=constant>map {|p| p.name}</span>  <span class=comments># standard map</span>
=> ["id", "amount", "date", "description", "balance"]
>> BankTransaction.columns.<span class=constant>map &#038;:name</span>  <span class=comments># Symbol.to_proc</span>
=> ["id", "amount", "date", "description", "balance"]
</pre>
<p>You can now type:</p>
<pre>
>> BankTransaction.columns.<span class=constant>select_primary</span>  <span class=comments># merge collector (select) and operator (primary returns true/false on a Column object)</span>
=> [#&lt;...MysqlColumn:0x3c8a4f0 @limit=11, @sql_type="int(11)", @primary=true, @type=:integer, @number=true, @name="id"&gt;]
</pre>
<p>Instead of:</p>
<pre>
>> BankTransaction.columns.<span class=constant>select {|c| c.primary}</span>
>> BankTransaction.columns.<span class=constant>select &#038;:primary</span>
</pre>
<h3>Use with ActiveRecords</h3>
<p>&#8220;Map by pluralisation&#8221; is truly wonderful in the console for exploring and collecting data models.</p>
<p>Without knowing a thing about the data model, I bet you can understand either of the following:</p>
<pre>
@transactions = BankTransaction.find :all, :conditions => ['date = ?', Date.today], :include => [:accounts => [:owner]]
return @transactions.<span class=constant>collect_accounts</span>.<span class=constant>select_overdrawn?</span>.<span class=constant>collect_owner</span>.<span class=constant>full_names</span>
</pre>
<p>Answer: the full name of each owner of an overdrawn bank accounts for all today&#8217;s bank transactions.</p>
<p>It reads well as there is a minimum of {, }, |, &#038;, : characters.</p>
<h3>Download</h3>
<p><a href="http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/">Code available here</a></p>
<h3>Tip for use with ActiveRecord Associations</h3>
<p>You may need to cast associations to Arrays.</p>
<pre>
@account.transactions.<span class=string>to_a</span>.<span class=constant>map_dates</span>
</pre>
<p>The result of the transactions assocation on the Account class is not an Array. My initial attempts to provide the &#8220;map by pluralisation&#8221; code (a method_missing) didn&#8217;t work, and casting it to an explicit Array using <code>to_a</code> seemed simple and harmless.</p>
<h3>Discussion of Syntax Ideas</h3>
<p><a href="http://www.ruby-forum.com/topic/82905">Ruby Forum</a></p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/09/07/map_by_method-the-final-announcement/' rel='bookmark' title='Permanent Link: map_by_method &#8211; the final announcement'>map_by_method &#8211; the final announcement</a> <small>I don&#8217;t really talk about my projects after I release...</small></li><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/03/02/5-things-im-in-love-with/' rel='bookmark' title='Permanent Link: 5 things I&#8217;m in love with'>5 things I&#8217;m in love with</a> <small>In no specific order, but enumerated for good measure: autotest...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/10/04/i-love-map-by-pluralisation/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>New magical version of Symbol.to_proc</title>
		<link>http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/</link>
		<comments>http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/#comments</comments>
		<pubDate>Thu, 28 Sep 2006 12:01:41 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[DSL]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[map_by_method]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/</guid>
		<description><![CDATA[Before the magic, let&#8217;s go through a Beginner&#8217;s Guide to Mapping, then Advanced Guide to Symbol.to_proc, and THEN, the magical version. Its worth it. Its sexy, nifty AND magical all at once. Beginner&#8217;s Guide to Mapping Need to invoke a method on each object in an array and return the result? # call 'to_i' on [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/07/23/magic-wiggly-lines-guessmethod-by-chris-shea/' rel='bookmark' title='Permanent Link: Magic Wiggly Lines => GuessMethod, by Chris Shea'>Magic Wiggly Lines => GuessMethod, by Chris Shea</a> <small>If you ever make time to code just for pleasure,...</small></li><li><a href='http://drnicwilliams.com/2007/04/12/magic-multi-connections-a-facility-in-rails-to-talk-to-more-than-one-database-at-a-time/' rel='bookmark' title='Permanent Link: Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;'>Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;</a> <small>At this point in time there’s no facility in Rails...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Before the magic, let&#8217;s go through a <strong>Beginner&#8217;s Guide to Mapping</strong>, then <strong>Advanced Guide to Symbol.to_proc</strong>, and THEN, the <strong>magical version</strong>. Its worth it. Its sexy, nifty AND magical all at once.</p>
<h3>Beginner&#8217;s Guide to Mapping</h3>
<p>Need to invoke a method on each object in an array and return the result?</p>
<pre>
<span class="comments"># call 'to_i' on each item of the list to return the list of numbers</span>
>> list = ['1',  '2', '3']
=> ["1", "2", "3"]
>> <span class="constant">list.map {|item| item.to_i}</span>
=> [1, 2, 3]
</pre>
<p>That is, we called the <code>to_i</code> method on each item of the list, thus converting the 3 strings into 3 integers. Of course, we could have called any method on any set of objects.</p>
<h3>Advanced Guide to Symbol.to_proc</h3>
<p>After doing that a few times, you start wishing there was simpler syntax. Enter: Symbol.to_proc</p>
<pre>
>> list.map <span class="constant">&#038;:to_i</span>
=> [1, 2, 3]
</pre>
<p>It looks like magic. Well it certainly doesn&#8217;t make any sense. But it works. (The secret: the <code>:to_id</code> symbol is cast into a Proc object by the leading <code>&#038;</code>. That is, it calls the <code>to_proc</code> method on the symbol. Rest of <a href="http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Tech/Ruby/ToProc.rdoc">explanation</a> <a href="http://www.sitepoint.com/blogs/2006/06/19/insta-block-with-symbolto_proc/">here</a>.)</p>
<h3>Magical version of Symbol.to_proc</h3>
<p>Quite frankly, that&#8217;s still a lot of syntax. Plus, I normally forget to added parentheses around the <code>&#038;:to_i</code>, and then latter I want to invoke another method on the result, so I need to add the parentheses which is a pain&#8230; anyway. I thought of something niftier and dare I say, more magical.</p>
<p>How about this syntax:</p>
<pre>
>> list.<span class="constant">to_is</span>
=> [1, 2, 3]
</pre>
<p>This syntax makes sense &#8211; <code>to_is</code> is the plural of <code>to_i</code> &#8211; its obvious you want the <code>to_i</code>&#8216;s of your list.</p>
<p><em>What&#8217;s happening here?</em>You pass the plural of the method name to the container and it invokes the singular of the method name upon the children using the <code>map</code> code above. Source is below.</p>
<p>More examples? Want to get the names of all the objects of a list? (assuming that each item in the list has a <code>name</code> method)</p>
<pre>
>> contacts.map {|contact| contact.name}
=> ['Dr Nic', 'Banjo', ...]
>> contacts.map &#038;:name
=> ['Dr Nic', 'Banjo', ...]
>> contacts.names
=> ['Dr Nic', 'Banjo', ...]
</pre>
<p>You pick your favourite. I love the last one.</p>
<p>Bonus examples:</p>
<pre>
>> (1..10).to_a.to_ss
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
>> (1..10).to_a.days
=> [86400, 172800, 259200, 345600, 432000, 518400, 604800, 691200, 777600, 864000]
>> [2,'two', :two].classes
=> [Fixnum, String, Symbol]
>> [2,'two', :two].classes.names
=> ["Fixnum", "String", "Symbol"]
>> [2,'two', :two].classes.names.lengths
=> [6, 6, 6]
</pre>
<p>So much happy syntax in one place!</p>
<p>UPDATE: After conversation on <a href="http://www.ruby-forum.com/topic/82905">Ruby Forums</a>, we&#8217;ve come up with some new syntax:</p>
<pre>
>> (1..5).to_a.map_days
=> [86400, 172800, 259200, 345600, 432000]
>> list = [nil, 1, 2, nil, 4]
=> [nil, 1, 2, nil, 4]
>> list.reject_nil?
=> [1, 2, 4]
</pre>
<p>Neat.</p>
<h3>How do I do this at home?</h3>
<p>Download and include this <a href="http://drnicwilliams.com/wp-content/uploads/2006/09/generic_map_to_proc.rb">mini-library</a>. Source below. Have fun.</p>
<pre>
module GenericMapToProc
  def self.included(base)
    super

    base.module_eval <<-EOS
      def method_missing(method, *args, &#038;block)
        super
      rescue NoMethodError
        error = $!
        begin
          re = /(map|collect|select|each|reject)_([\\\\w\\\\_]+\\\\??)/
          if (match = method.to_s.match(re))
            iterator, callmethod = match[1..2]
            return self.send(iterator) {|item| item.send callmethod}
          end
          return self.map {|item| item.send method.to_s.singularize.to_sym}
        rescue NoMethodError
          nil
        end
        raise error
      end
    EOS
  end
end

unless String.instance_methods.include? "singularize"
  String.module_eval <<- EOS
    def singularize
      self.gsub(/e?s\Z/,'')
    end
  EOS
end

# Add this to the Array class
Array.send :include, GenericMapToProc
</pre>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2007/08/12/map_by_method-now-works-with-activerecord-associations/' rel='bookmark' title='Permanent Link: map_by_method now works with ActiveRecord associations'>map_by_method now works with ActiveRecord associations</a> <small>I was always annoyed that map_by_method was broken for ActiveRecord...</small></li><li><a href='http://drnicwilliams.com/2007/07/23/magic-wiggly-lines-guessmethod-by-chris-shea/' rel='bookmark' title='Permanent Link: Magic Wiggly Lines => GuessMethod, by Chris Shea'>Magic Wiggly Lines => GuessMethod, by Chris Shea</a> <small>If you ever make time to code just for pleasure,...</small></li><li><a href='http://drnicwilliams.com/2007/04/12/magic-multi-connections-a-facility-in-rails-to-talk-to-more-than-one-database-at-a-time/' rel='bookmark' title='Permanent Link: Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;'>Magic Multi-Connections: A &#8220;facility in Rails to talk to more than one database at a time&#8221;</a> <small>At this point in time there’s no facility in Rails...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/09/28/new-magical-version-of-symbolto_proc/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
