<?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; Meta-Programming</title>
	<atom:link href="http://drnicwilliams.com/category/meta-programming/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>Mon, 15 Mar 2010 20:51:48 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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; user = User.find_by_name "Dr Nic"
&#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>Another use for const_missing &#8211; generating unicode characters in strings</title>
		<link>http://drnicwilliams.com/2007/06/05/another-use-for-const_missing-generating-unicode-characters-in-strings/</link>
		<comments>http://drnicwilliams.com/2007/06/05/another-use-for-const_missing-generating-unicode-characters-in-strings/#comments</comments>
		<pubDate>Tue, 05 Jun 2007 11:38:31 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/06/05/another-use-for-const_missing-generating-unicode-characters-in-strings/</guid>
		<description><![CDATA[I just spotted something very sexy on the RubyForge News-vine (subscribe to all RubyForge news and new releases): a new use for Ruby&#8217;s const_missing method &#8211; charesc.
If the unicode character for ü is #00FC, then you can insert that into a string using the global constant U00FC. Where is U00FC defined? Its not. You ask [...]


Related posts:<ol><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><li><a href='http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/' rel='bookmark' title='Permanent Link: [BTS] Magic Models &#8211; Class creation'>[BTS] Magic Models &#8211; Class creation</a> <small>[BTS] = Behind the Scenes; also a news-like TV show...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>I just spotted <a href="http://rubyforge.org/forum/forum.php?forum_id=14933">something very sexy</a> on the RubyForge News-vine (subscribe to all RubyForge <a href="http://rubyforge.org/export/rss_sfnews.php">news</a> and <a href="http://rubyforge.org/export/rss_sfnewreleases.php">new releases</a>): a new use for Ruby&#8217;s <code>const_missing</code> method &#8211; <a href="http://rubyforge.org/projects/charesc">charesc</a>.</p>
<p>If the unicode character for <strong>ü</strong> is #00FC, then you can insert that into a string using the global constant <code>U00FC</code>. Where is <code>U00FC</code> defined? Its not. You ask for it and a unicode string is returned. Oohlala.</p>
<p><strike>For the demo we&#8217;ll use a Rails app as it has built-in unicode support to make the output look nicer:</strike></p>
<p>Using any old irb:</p>
<pre>$ sudo gem install charesc
$ irb
>> $KCODE = "u"  # thanks Paul Battley
>> require 'rubygems'
>> require 'charesc'
>> "charesc is made by Martin D#{U00FC}rst"
=> "charesc is made by Martin Dürst"
>> U00FC
=> "ü"
</pre>
<p>If you have any more fun uses for <code>const_missing</code> please let me know. Feed my fetish.</p>


<p>Related posts:<ol><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><li><a href='http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/' rel='bookmark' title='Permanent Link: [BTS] Magic Models &#8211; Class creation'>[BTS] Magic Models &#8211; Class creation</a> <small>[BTS] = Behind the Scenes; also a news-like TV show...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/06/05/another-use-for-const_missing-generating-unicode-characters-in-strings/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Spring Collection &#8211; the Modular Magic Models</title>
		<link>http://drnicwilliams.com/2007/04/12/spring-collection-the-modular-magic-models/</link>
		<comments>http://drnicwilliams.com/2007/04/12/spring-collection-the-modular-magic-models/#comments</comments>
		<pubDate>Thu, 12 Apr 2007 06:27:52 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Magic Models]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/04/12/spring-collection-the-modular-magic-models/</guid>
		<description><![CDATA[Dr Nic&#8217;s Magic Models are like cheating on your taxes but without jail time. Its like filling out your tax return, and the tax office saying, &#8220;No, no, you keep your money &#8211; this year&#8217;s on us.&#8221; 
Its like coming home and dinner is already cooked for you.
Its like being good looking and funny.
But this [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2008/06/06/composite-primary-keys-goes-100-for-rails-21/' rel='bookmark' title='Permanent Link: Composite Primary Keys goes 1.0.0 for Rails 2.1'>Composite Primary Keys goes 1.0.0 for Rails 2.1</a> <small>Two years ago Dave Thomas did a keynote at the...</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><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></ol>]]></description>
			<content:encoded><![CDATA[<p>Dr Nic&#8217;s Magic Models are like cheating on your taxes but without jail time. Its like filling out your tax return, and the tax office saying, &#8220;No, no, you keep your money &#8211; this year&#8217;s on us.&#8221; </p>
<p>Its like coming home and dinner is already cooked for you.</p>
<p>Its like being good looking <em>and</em> funny.</p>
<p>But this is Ruby, so we call it <em>Magic!</em></p>
<p>With the release of <a href="http://magicmodels.rubyforge.org/dr_nic_magic_models">0.9.1</a>, you can configure how much cheating, lying and thievery &#8211; err, magic &#8211; you want.</p>
<p>Already got model classes, but you haven&#8217;t gotten around to writing validations for some of them?</p>
<pre>class Person < ActiveRecord::Base
  generate_validations
end
</pre>
<p>As always, if you don't have a <code>Person</code> class, you'll get it for free plus validations.</p>
<p>As always, with automatically created classes AND pre-existing classes, if your schema supports an association and you ask for it it will be there. If you don't want a certain association to exist in your application... don't ask for it. The Magic Models are no place for enforcing law and order.</p>
<p>The other publicly announced, above board, for-sale to the general public feature you might like to know about is <strong>Magic Modules</strong>.</p>
<p>You can now use modules to specify common features of magic models. Currently supported is table name prefixes. If you need anything else, <a href="http://groups.google.com/group/magicmodels">ask</a>. </p>
<pre>module Admin
  magic_module :prefix_table_name => 'admin_'
end

Admin::Permission.table_name # => 'admin_permissions'
</pre>
<p>The upcoming Magic Multi-Connections use this same concept to allow modules to specify different database connections instead of using superclasses. All this and more in the <a href="http://drnicwilliams.com/2007/04/10/magic-models-the-spring-collection/" title='Dr Nic    &raquo; Magic Models: the Spring collection'>Magic Models: Spring collection</a> series.</p>
<p>The end.</p>
<p>Ok, there's more. Secret stuff. Backdoor hooks into a Harry Potter world of mystery. Ways to execute code, import modules, and what-not upon newly created magic models. Awesome magicalness.</p>
<p>But you'll need to read the code to find them, and have some imagination as to what you'd want to dynamically do to your generated classes.</p>
<p>But as an example to prod your brain. Our schema at work supports date-ranging on many tables. The table will have a primary id key, plus another primary key - <code>effective_start_date</code>. All these tables end with the suffix '_history'. So when a new model class is created, I use the hooks to test the table name suffix, and if <code>table_name =~ /_history$/</code> then I include a module that adds more methods etc to these date-ranged classes.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2008/06/06/composite-primary-keys-goes-100-for-rails-21/' rel='bookmark' title='Permanent Link: Composite Primary Keys goes 1.0.0 for Rails 2.1'>Composite Primary Keys goes 1.0.0 for Rails 2.1</a> <small>Two years ago Dave Thomas did a keynote at the...</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><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></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/04/12/spring-collection-the-modular-magic-models/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Meta-Magic in Ruby: Dr Nic Unplugged in Stockholm</title>
		<link>http://drnicwilliams.com/2007/03/22/meta-magic-in-ruby-presentation/</link>
		<comments>http://drnicwilliams.com/2007/03/22/meta-magic-in-ruby-presentation/#comments</comments>
		<pubDate>Thu, 22 Mar 2007 05:52:35 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[BTS]]></category>
		<category><![CDATA[Magic Models]]></category>
		<category><![CDATA[Magic Wiggly Lines]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Trick]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2007/03/22/meta-magic-in-ruby-presentation/</guid>
		<description><![CDATA[Last nights&#8217; Ruby meeting in Stockholm had a great turn out and starred Ola Bini sharing the latest and greatest about JRuby, and myself giving an overview on the wonders of Meta-Magic in Ruby.
I&#8217;ll write a separate post on Ola&#8217;s presentation shortly. It was awesome and I videoed it. Hehehe.

But first and foremost, lets talk [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</small></li><li><a href='http://drnicwilliams.com/2008/12/11/future-proofing-your-ruby-code/' rel='bookmark' title='Permanent Link: Future proofing your Ruby code. Ruby 1.9.1 is coming.'>Future proofing your Ruby code. Ruby 1.9.1 is coming.</a> <small> Bugger. I&#8217;m a Ruby monogamist. I use the Ruby...</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Last nights&#8217; Ruby meeting in <a href="http://www.rails.se/rails/show/Railstr%C3%A4ff+20+Mars+2007">Stockholm</a> had a great turn out and starred <a href="http://ola-bini.blogspot.com/">Ola Bini</a> sharing the latest and greatest about <a href="http://jruby.codehaus.org/">JRuby</a>, and myself giving an overview on the wonders of Meta-Magic in Ruby.</p>
<p>I&#8217;ll write a separate post on Ola&#8217;s presentation shortly. It was awesome and I videoed it. <em>Hehehe.</em></p>
<div>
But first and foremost, lets talk about me. Or rather, let&#8217;s talk about my talk, which was also videoed.</p>
<div style="float: right" >
<a id="p157" href="http://drnicwilliams.com/wp-content/uploads/2007/03/meta-magic-in-ruby-stockholm-2007-03-20.pdf" title="Meta-magic in Ruby - Weaponry"><img id="image159" src="http://drnicwilliams.com/wp-content/uploads/2007/03/pdf-file.thumbnail.jpg" alt="PDF File" /><br />Meta-magic in Ruby<br />- Weaponry.pdf</a></div>
<p>Meta-magic in a programming language is as important to programmers as changeable ring tones are to teenagers. Authors of programming languages cannot provide every feature to everyone, so it is so wonderful to be able to add new language features and extensions that you want. Everyone knows you can add Jessica Simpson as your mobile ring tone, but not all programmers know that you can add new features to their programming world. </p>
<p>So here is an overview to a new world of happiness. It also overviews how the <a href="http://magicmodels.rubyforge.org">Magic Models</a> work, and introduces a new gem I&#8217;m working on &#8211; the <strong>Magic Wiggly Lines</strong> &#8211; described as &#8220;<a href="http://ola-bini.blogspot.com/2007/03/post-rails-meetup.html">genius or insane</a>&#8221;</p>
</div>
<p><embed style="width:500px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=-8652861546168277758&#038;hl=en" flashvars=""> </embed></p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</small></li><li><a href='http://drnicwilliams.com/2008/12/11/future-proofing-your-ruby-code/' rel='bookmark' title='Permanent Link: Future proofing your Ruby code. Ruby 1.9.1 is coming.'>Future proofing your Ruby code. Ruby 1.9.1 is coming.</a> <small> Bugger. I&#8217;m a Ruby monogamist. I use the Ruby...</small></li><li><a href='http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/' rel='bookmark' title='Permanent Link: Unit Testing iPhone apps with Ruby: rbiphonetest'>Unit Testing iPhone apps with Ruby: rbiphonetest</a> <small> Everything to love about Ruby: the concise, powerful language;...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2007/03/22/meta-magic-in-ruby-presentation/feed/</wfw:commentRss>
		<slash:comments>10</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  # map by [...]


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>Extending _why&#8217;s Creature class</title>
		<link>http://drnicwilliams.com/2006/08/28/extending-_whys-creature-class/</link>
		<comments>http://drnicwilliams.com/2006/08/28/extending-_whys-creature-class/#comments</comments>
		<pubDate>Mon, 28 Aug 2006 21:06:40 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[BTS]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/08/28/extending-_whys-creature-class/</guid>
		<description><![CDATA[Many Rubist&#8217;s first explanation of metaprogramming is by why the lucky stiff (_why)&#8217;s Why&#8217;s (Poignant) Guide to Ruby, chapter 6, section 3.
You go on a dragon-hunting, adventure game using sexy Ruby syntax (a domain-specific language/DSL for adventure games?). Here is some sample syntax for defining a monster class:

 class Dragon < Creature
   life [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</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/03/extending-rails-is-like-converting-a-mini-cooper-into-a-rocket-car/' rel='bookmark' title='Permanent Link: Extending Rails is like converting a Mini Cooper into a Rocket Car'>Extending Rails is like converting a Mini Cooper into a Rocket Car</a> <small>Not only is Ruby on Rails open sourced so all...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Many Rubist&#8217;s first explanation of metaprogramming is by <a href="http://redhanded.hobix.com/">why the lucky stiff</a> (_why)&#8217;s <a href="http://poignantguide.net/ruby/index.html">Why&#8217;s (Poignant) Guide to Ruby</a>, chapter 6, <a href="http://poignantguide.net/ruby/chapter-6.html#section3">section 3</a>.</p>
<p>You go on a dragon-hunting, adventure game using sexy Ruby syntax (a domain-specific language/DSL for adventure games?). Here is some sample syntax for defining a monster class:</p>
<pre>
 class Dragon < Creature
   life 1340     # tough scales
   strength 451  # bristling veins
   charisma 1020 # toothy smile
   weapon 939    # fire breath
 end
</pre>
<p>The <code>life</code>, <code>strength</code>, <code>charisma</code> and <code>weapon</code> class methods are generated by a <code>traits</code> class method called against the <code>Creature</code> class (read the chapter). </p>
<pre>
class Creature
  traits :life, :strength, :charisma, :weapon
end
</pre>
<p>Read this chapter section many times and admire the beauty of the idea (and amuse yourself with his writing style!).</p>
<p>But there is one small improvement that could be made: currently, after setting the trait methods (e.g. <code>life 1340</code> sets the life trait to 1340), you cannot access the class's trait values directly via their original trait method. That is, you cannot call <code>Dragon.life</code> to retrieve the value 1340.</p>
<p>This is due to a limitation of the <code>define_method</code> method being used. The relevant code from _why's book is:</p>
<pre>
   def self.traits( *arr )
     # 2. Add a new class method to for each trait.
     arr.each do |a|
       metaclass.instance_eval do
         <span class="constant">define_method( a ) do |val|</span>
           @traits ||= {}
           @traits[a] = val
         end
       end
     end
</pre>
<p>The method creator <code>define_method</code> uses a <a href="http://www.rubycentral.com/book/tut_containers.html">block</a> to define the generated method body. The parameters for the block (<code>val</code> in the example above) become the arguments of the method once its been added to the class. That is, if we call <code>traits :life</code> on our Creature class, then a class method will be generated that requires one argument - the value of the trait. That is, it will generate the following method:</p>
<pre>
class Creature
  def life(val)
    @traits ||= {}
    @traits[:life] = val
  end
end
</pre>
<p>Now, back to the problem. How do we support the syntax <code>Dragon.life</code>? To achieve this, the generated method would need to look like:</p>
<pre>
class Creature
  def life(<span class="constant">val = nil</span>)
    @traits ||= {}
    <span class="constant">return @traits[:life] if not val</span>
    @traits[:life] = val
  end
end
</pre>
<p>That is, we need a default value for our method argument. But... blocks don't allow parameters to have default values. We cannot do the following:</p>
<pre>
         define_method( a ) do |<span class="constant">val = nil</span>|
           @traits ||= {}
           return @traits[a] if not val
           @traits[a] = val
         end
</pre>
<p>A pity, yes.</p>
<p>So, we need to generate our methods differently. The solution is as follows:</p>
<pre>
      metaclass.class_eval <<-EOS
        def #{a}(val=nil)
          @traits ||= {}
          return @traits[:#{a}] if not val
          @traits[:#{a}] = val
        end
      EOS
</pre>
<p>The <code>eval</code> methods allow a string to be passed to them. So, we shall pass it a string that defines a new method the old fashioned way: using the <code>def</code> method constructor. Thus it allows us to have default values for our arguments. </p>
<p><a href="http://en.wikipedia.org/wiki/Q.E.D.">QED</a>.</p>
<p>ALTERNATIVE from Chris @ <a href="http://errthblog.com">Errtheblog.com</a></p>
<p>Use the splat! (*) to allow zero or more arguments. Pluck the first one off to represent the incoming argument or nil.</p>
<pre>
def self.traits( *arr )
  arr.each do |a|
    metaclass.instance_eval do
       define_method( a ) do |<span class="constant">*val</span>|
         <span class="constant">val = val.first</span>
         @traits ||= {}
         return @traits[a] if not val
         @traits[a] = val
       end
     end
  end
end
</pre>
<p>There are unanswered questions about its support for 2+ arguments (where we only need support for 0 or 1) that shall remain unanswered for the sake of this simple hack. But feel free to start throwing exceptions around if your users need protection from themselves.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</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/03/extending-rails-is-like-converting-a-mini-cooper-into-a-rocket-car/' rel='bookmark' title='Permanent Link: Extending Rails is like converting a Mini Cooper into a Rocket Car'>Extending Rails is like converting a Mini Cooper into a Rocket Car</a> <small>Not only is Ruby on Rails open sourced so all...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/08/28/extending-_whys-creature-class/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>So, cattr_accessor doesn&#8217;t work like it should?</title>
		<link>http://drnicwilliams.com/2006/08/27/so-cattr_accessor-doesnt-work-like-it-should/</link>
		<comments>http://drnicwilliams.com/2006/08/27/so-cattr_accessor-doesnt-work-like-it-should/#comments</comments>
		<pubDate>Sun, 27 Aug 2006 15:59:20 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[BTS]]></category>
		<category><![CDATA[DSL]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/08/27/so-cattr_accessor-doesnt-work-like-it-should/</guid>
		<description><![CDATA[Rails&#8217; active_support library adds some wonderful functions into standard Ruby classes. Some we all use day-in-day out are attr_accessor and its class-level equivalent, cattr_accessor.
But cattr_accessor doesn&#8217;t work the way you (read, &#8220;me&#8221;) thought at first glance when you use subclasses. I thought if I declared a class accessor in the superclass, then I would have [...]


Related posts:<ol><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/09/07/turn-based-game-dsl/' rel='bookmark' title='Permanent Link: Turn-based game DSL'>Turn-based game DSL</a> <small>Late in the night, whilst the baby feeds, I continue...</small></li><li><a href='http://drnicwilliams.com/2006/08/28/extending-_whys-creature-class/' rel='bookmark' title='Permanent Link: Extending _why&#8217;s Creature class'>Extending _why&#8217;s Creature class</a> <small>Many Rubist&#8217;s first explanation of metaprogramming is by why the...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p>Rails&#8217; <code>active_support</code> library adds some wonderful functions into standard Ruby classes. Some we all use day-in-day out are <code>attr_accessor</code> and its class-level equivalent, <code>cattr_accessor</code>.</p>
<p>But <code>cattr_accessor</code> doesn&#8217;t work the way you (read, &#8220;me&#8221;) thought at first glance when you use subclasses. I thought if I declared a class accessor in the superclass, then I would have independent class attributes for all my subclasses. Apparently not&#8230;</p>
<pre>
>> class Parent; <strong>cattr_accessor</strong> :val; end
=> [:val]
>> class Child1 < Parent; end
=> nil
>> class Child2 < Parent; end
=> nil
>> Child1.val = 4
=> 4
>> Child2.val
=> 4
>> Child2.val = 5
=> 5
>> Child1.val
=> 5
</pre>
<p><code>Child1.val</code> and <code>Child2.val</code> seem to be the same value. Not very independent at all. Internally, the classes share a common class attribute. This is useful in certain circumstances, but not what I was looking for.</p>
<p>Instead, I found <code>class_inheritable_accessor</code>.</p>
<pre>
>> class Parent; <strong>class_inheritable_accessor</strong> :val; end
=> [:val]
>> class Child1 < Parent; end
=> nil
>> class Child2 < Parent; end
=> nil
>> Child1.val = 4
=> 4
>> Child2.val = 4
=> 4
>> Child2.val = 5
=> 5
>> Child1.val
=> 4
</pre>
<p>Lovely. Each subclass will have an independent value once you&#8217;ve assigned it a value explicitly, else it will pick up the value from its superclass.</p>
<p>UPDATE: <code>class_inheritable_accessor</code> and co. actually clone the superclass&#8217;s inherited attributes, rather than just referencing them.</p>


<p>Related posts:<ol><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/09/07/turn-based-game-dsl/' rel='bookmark' title='Permanent Link: Turn-based game DSL'>Turn-based game DSL</a> <small>Late in the night, whilst the baby feeds, I continue...</small></li><li><a href='http://drnicwilliams.com/2006/08/28/extending-_whys-creature-class/' rel='bookmark' title='Permanent Link: Extending _why&#8217;s Creature class'>Extending _why&#8217;s Creature class</a> <small>Many Rubist&#8217;s first explanation of metaprogramming is by why the...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/08/27/so-cattr_accessor-doesnt-work-like-it-should/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>[BTS] Magic Models vs ActiveRecords &#8211; Efficiency</title>
		<link>http://drnicwilliams.com/2006/08/22/bts-magic-models-vs-activerecords-efficiency/</link>
		<comments>http://drnicwilliams.com/2006/08/22/bts-magic-models-vs-activerecords-efficiency/#comments</comments>
		<pubDate>Tue, 22 Aug 2006 15:11:41 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[BTS]]></category>
		<category><![CDATA[Magic Models]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/08/22/bts-magic-models-vs-activerecords-efficiency/</guid>
		<description><![CDATA[Dr Nic&#8217;s Magic Models are magical, that goes without saying. But are they efficient at being magical? Do you get the same speed in your application as if you explicitly defined your classes and your associations will your application execute faster?
Yes. The cost of accessing a Magic Model and a normal ActiveRecord is exactly the [...]


Related posts:<ol><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><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></ol>]]></description>
			<content:encoded><![CDATA[<p>Dr Nic&#8217;s Magic Models are magical, that goes without saying. But are they efficient at being magical? Do you get the same speed in your application as if you explicitly defined your classes and your associations will your application execute faster?</p>
<p><strong>Yes</strong>. The cost of accessing a Magic Model and a normal ActiveRecord is exactly the same &#8211; once the Magic Model has been initially generated. Its just a normal ActiveRecord like all your other ActiveRecords: they are loaded into memory when you first ask for them. Normal ActiveRecords are loaded into memory from your <code>/app/models/<model_name>.rb</code> file; Magic Models are generated classes. The Magic Models would in fact be quicker to load as there is no file access required.</p>
<p>The cost of accessing Automatic Associations versus normal Active Record associations is also exactly the same. To understand the inner workings of associations, see err.the_blog&#8217;s <a href="http://errtheblog.com/post/20">latest article</a>.</p>
<p>The point to take away from the discussion is that associations are a generated method on your class. Once you&#8217;ve generated it once (at the time you call <code>has_many</code> for example), you have it permanently. So there is only a small, one-time cost for the Automatic Associations &#8211; to see which association to generate for the incoming method call. But once you&#8217;ve generated the association, its yours permanently. </p>


<p>Related posts:<ol><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><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></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/08/22/bts-magic-models-vs-activerecords-efficiency/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[BTS] Magic Models &#8211; Class creation</title>
		<link>http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/</link>
		<comments>http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/#comments</comments>
		<pubDate>Thu, 10 Aug 2006 13:01:39 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[BTS]]></category>
		<category><![CDATA[Magic Models]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/</guid>
		<description><![CDATA[[BTS] = Behind the Scenes;  also a news-like TV show we used to watch as school kids (in Australia) that explored world news events and then our teachers would make us write reports about it. (UPDATE: this is a lie; it was BTN &#8211; Behind the News) Anyway&#8230;. 
Class creation &#8211; the magical way
As [...]


Related posts:<ol><li><a href='http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/' rel='bookmark' title='Permanent Link: First look at rails 3.0.pre'>First look at rails 3.0.pre</a> <small> This article is out of date in some aspects....</small></li><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</small></li><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></ol>]]></description>
			<content:encoded><![CDATA[<p>[BTS] = Behind the Scenes;  also a news-like TV show we used to watch as school kids (in Australia) that explored world news events and then our teachers would make us write reports about it. (UPDATE: this is a lie; it was BTN &#8211; Behind the News) Anyway&#8230;. </p>
<h3>Class creation &#8211; the magical way</h3>
<p>As an educational exercise, it is definitely interesting to look at how the Magic Model&#8217;s Invisible Classes <a href="#footer-1">[1]</a> are generated. Inside the gem <a href="#footer-2">[2]</a>, please turn to the file <code>/lib/module.rb</code> I&#8217;ve broken it up below too.</p>
<pre syntax="ruby">
class Module
  alias :normal_const_missing :const_missing

  def const_missing(class_id)
    begin; return normal_const_missing(class_id); rescue; end
</pre>
<p>If you open the Irb/Console and type <code>Foo</code>, you&#8217;ll get an &#8220;unitialized constant Foo&#8221; error. This is raised by the <code>const_missing</code> method in the <code>Module</code> class. Yes, there&#8217;s a core class called Module. Type <code>Module.methods.sort</code> to see all the fun things it can do, or look up the <a href="http://ruby-doc.org/core/classes/Module.html">API</a>.</p>
<p>Like so many things in Ruby you can override this method, just like you might override the <code>method_missing</code> on a class (Rails does this on its ActiveRecord to support the <code>find_by_...</code> magical methods.)</p>
<p>When you load Magic Models (via the <code>require 'dr_nic_magic_models'</code> statement) it renames/aliases the current const_missing method and then overrides it.</p>
<p>The first thing it does it call the original const_missing to see if it returns anything useful. Why? Rails also overrides this method. Rails doesn&#8217;t preload all your model classes at start up. Instead when you first ask for a model class, it loads it via the const_missing method call. So Magic Models won&#8217;t do anything until Rails has had a chance to try an load the class from a <code>app/models/foo.rb</code> file, for example.</p>
<pre syntax="ruby">
    unless table_name = DrNicMagicModels::Schema.models[class_id]
      raise NameError.new("uninitialized constant #{class_id}") if
                    DrNicMagicModels::Schema.models.enquired? class_id
    end
</pre>
<p>The DNMM::Schema class is in charge of mapping an unknown class name (class_id) to one of your database&#8217;s tables. To prevent nasty infinite recursion, we raise the &#8220;uninitialized constant&#8221; error if another const_missing request comes in for the same class_id.</p>
<pre syntax="ruby">
    klass = Class.new ActiveRecord::Base
    const_set class_id, klass
</pre>
<p>The Class <a href="http://ruby-doc.org/core/classes/Class.html">API</a> takes a superclass as a parameter. Here, we want our Invisible Model to be an ActiveRecord.</p>
<p>By setting the anonymous class object to a constant value, e.g. Foo, it <a href="http://ruby-doc.org/core/classes/Class.html#M002078">automatically names the class</a>. E.g. <code>klass.name == 'Foo'</code></p>
<pre syntax="ruby">
    klass.set_table_name table_name
</pre>
<p>Finally, we force the new ActiveRecord class to use the table name that DNMM::Scheme found. You just can&#8217;t trust that the class will know what its table name is. </p>
<p>If you find yourself using this sort of code, then here&#8217;s some bonus code. When you create your class, you can install some code at the same time.</p>
<pre syntax="ruby">
    klass_code = %q{def to_s; 'I''m magically generated'; end }
    klass_code = lambda {klass_code}
    klass = Class.new ActiveRecord::Base, &#038;klass_code
</pre>
<h3>Feedback</h3>
<p>Was this easy to read? Too compact/too long? Let me know below.</p>
<p>If you go on and build something magically cool after reading this, definitely let me know.</p>
<h3>Moral of the Story</h3>
<p>You can live as a programmer without ever knowing any meta-programming features of Ruby. Heck, we all did it in Java/C++/C# and never knew we needed them. A lot of powerful API features exist in Rails that you&#8217;d never be able to build in many other languages; the ActiveRecord library is a tribute to meta-programming magic.</p>
<p>UPDATE: I had previously called <code>Module</code> a module, when its a class. Fixed.</p>
<p><a name="footer-1">[1]  I just like calling them Invisible Models.</p>
<p><a name="footer-2">[2]  Gems are installed inside your Ruby installation folder. Try something like </code>....\lib\ruby\gems\1.8\gems\</code> and you'll see all your favourite gems, like <a href="http://weblog.rubyonrails.com/2006/8/9/rails-1-1-5-mandatory-security-patch-and-other-tidbits">rails-1.1.5</a>, active-record-1.14.4, etc.</p>


<p>Related posts:<ol><li><a href='http://drnicwilliams.com/2009/11/03/first-look-at-rails-3-0-pre/' rel='bookmark' title='Permanent Link: First look at rails 3.0.pre'>First look at rails 3.0.pre</a> <small> This article is out of date in some aspects....</small></li><li><a href='http://drnicwilliams.com/2009/04/15/cucumber-building-a-better-world-object/' rel='bookmark' title='Permanent Link: Cucumber: building a better World (object)'>Cucumber: building a better World (object)</a> <small>How to write helper libraries for your Cucumber step definitions...</small></li><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></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/08/10/bts-magic-models-class-creation/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>[ANN] Dr Nic&#8217;s Magic Models</title>
		<link>http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/</link>
		<comments>http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/#comments</comments>
		<pubDate>Mon, 07 Aug 2006 20:54:46 +0000</pubDate>
		<dc:creator>Dr Nic</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Magic Models]]></category>
		<category><![CDATA[Meta-Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/</guid>
		<description><![CDATA[Welcome! Welcome! Welcome! Ladies and Gentlemen, today you shall be thrilled and dazzled by wonders of magical mystery. Dr Nic&#8217;s Magic Models will now be unveiled to all. Mystery and magic that you will be able to perform at home.
Within your ActiveRecord models, never again will you need to write: 

validates_presence_of validations
has_many and belongs_to statements
has_many [...]


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/05/23/dr-nics-magic-show-at-rejectconf2007/' rel='bookmark' title='Permanent Link: Dr Nic&#8217;s Magic Show at RejectConf2007'>Dr Nic&#8217;s Magic Show at RejectConf2007</a> <small>Update: there is a patch available for edge rails to...</small></li></ol>]]></description>
			<content:encoded><![CDATA[<p><img id="image13" src="http://drnicwilliams.com/wp-content/uploads/2006/08/magic-hat.jpg" alt="Magic hat" width=100 style="float: right;" />Welcome! Welcome! Welcome! Ladies and Gentlemen, today you shall be thrilled and dazzled by wonders of magical mystery. Dr Nic&#8217;s Magic Models will now be unveiled to all. Mystery and magic that you will be able to perform at home.<br />
Within your ActiveRecord models, <strong>never again</strong> will you need to write: </p>
<ul>
<li><code>validates_presence_of</code> validations</li>
<li><code>has_many</code> and <code>belongs_to</code> statements</li>
<li><code>has_many :through</code> statements!!</li>
</ul>
<p>And for the finale, you will be amazed and astounded as you watch ActiveRecord models appear from nowhere. No class definition, just any old database tables you have lying around the home is all you&#8217;ll need to perform this trick!</p>
<p>No cover charge. No free steak knives. No heavy lifting involved.</p>
<p>Installation, DIY magical instructions, and a world of mystery awaits you at:<br />
<a href="http://magicmodels.rubyforge.org">http://magicmodels.rubyforge.org</a></p>
<p>Original forum notification: <a href="http://www.ruby-forum.com/topic/74957">http://www.ruby-forum.com/topic/74957</a></p>
<p>UPDATE: <a href="http://digg.com/software/Ruby_on_Rails_easier_than_ever">Digg this!</a></p>
<p>UPDATE 2: Conversations about the Magic Models have been conducted on Ruby/Rails forums too:</p>
<ul>
<li><a href="http://www.ruby-forum.com/topic/76331">Ruby on Rails forum</a></li>
<li><a href="http://www.ruby-forum.com/topic/76332">Ruby Forum</a></li>
</ul>


<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/05/23/dr-nics-magic-show-at-rejectconf2007/' rel='bookmark' title='Permanent Link: Dr Nic&#8217;s Magic Show at RejectConf2007'>Dr Nic&#8217;s Magic Show at RejectConf2007</a> <small>Update: there is a patch available for edge rails to...</small></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://drnicwilliams.com/2006/08/07/ann-dr-nics-magic-models/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>
