<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-16766120</id><updated>2011-12-19T10:26:13.612+01:00</updated><title type='text'>Liquid Development</title><subtitle type='html'>The Art of Shaping Software</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>93</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-16766120.post-1038199561299011987</id><published>2007-09-24T11:50:00.001+02:00</published><updated>2007-09-24T11:50:20.501+02:00</updated><title type='text'>Getting Autotest to work on Windows for Ruby projects</title><content type='html'>This seems blogworthy, as I have spent much longer than I wanted to find a solution.&lt;br&gt;&lt;br&gt;I was trying to run autotest - of the zentest package - on a ruby project on windows, but autotest didn&amp;#39;t seem to be able to pick up changes to my files. &lt;br&gt;&lt;br&gt;I will not pretend to have understood exactly what made it work for me, but these are things that I did and that might have helped.&lt;br&gt;&lt;br&gt;Setting the &lt;span style="font-weight: bold;"&gt;HOME &lt;/span&gt;variable:&lt;br&gt;&lt;br&gt; &lt;span style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;set HOME=&amp;quot;c:\Documents and Settings\my_username_here&amp;quot;&lt;/span&gt;&lt;br style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;&lt;br&gt;moving my project files into a  &lt;span style="font-weight: bold;"&gt;lib &lt;/span&gt;directory and my test files into a &lt;span style="font-weight: bold;"&gt;test &lt;/span&gt;directory:&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;myproject &lt;/span&gt;&lt;br style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;&lt;span style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;myproject/lib&lt;/span&gt;&lt;br style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;  &lt;span style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;myproject/test&lt;/span&gt;&lt;br style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br&gt;&lt;/span&gt;going to the project directory and running autotest: &lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold; background-color: rgb(153, 255, 153);"&gt;cd myproject&lt;br&gt;&lt;span style="font-weight: bold;"&gt;autotest -v&lt;/span&gt;&lt;/span&gt;&lt;br style="background-color: rgb(153, 255, 153);"&gt;&lt;br&gt;This should work. Every time I save a test file or a lib file, autotest picks up the changes and runs the tests. &lt;br&gt;&lt;br&gt;thanks to &lt;a href="http://ph7spot.com/articles/getting_started_with_autotest" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Philippe Hanrigou for pointing out the right heuristics&lt;/a&gt;!&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-1038199561299011987?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/1038199561299011987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=1038199561299011987' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/1038199561299011987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/1038199561299011987'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2007/09/getting-autotest-to-work-on-windows-for.html' title='Getting Autotest to work on Windows for Ruby projects'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-7590239772692189656</id><published>2007-08-06T16:52:00.001+02:00</published><updated>2007-08-06T16:52:24.995+02:00</updated><title type='text'>Year 2012</title><content type='html'>According to the current growth rates in five years we will be able to buy storage for about 30 years of audio/video of our life for 100 euros.&lt;br&gt;It will be cheaper to record everything that happens to us and search it than to take notes or even think that we should be taking notes.&lt;br&gt;&lt;br&gt; How is this going to change how we search/organize information?&lt;br&gt;How is this going to change our sense of identity? &lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-7590239772692189656?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/7590239772692189656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=7590239772692189656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/7590239772692189656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/7590239772692189656'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2007/08/year-2012.html' title='Year 2012'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-6256636650087136800</id><published>2007-07-05T01:01:00.001+02:00</published><updated>2007-07-05T01:01:38.168+02:00</updated><title type='text'>Ruby Social Club night</title><content type='html'>The &lt;font size="4"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt;Ruby Social Club&lt;/span&gt;&lt;/font&gt; meetups have started and they are coming on one after the other! &lt;br&gt;drop us a call if you are in Italy. We are &lt;font size="4"&gt;&lt;a href="http://ruby-it.org/pages/Persone"&gt; all over the place&lt;/a&gt;&lt;/font&gt;, so don&amp;#39;t be shy and get in touch.&lt;br&gt;This is &lt;a href="http://www.rubysocialclub.net/moin.fcg/serata_businessbase"&gt;a short report&lt;/a&gt; on the evening on the new RSC wiki (thanks &lt;font size="6"&gt; &lt;a style="color: rgb(0, 153, 0);" href="http://tempe.st/"&gt;intinig!&lt;/a&gt;&lt;/font&gt;)&lt;br&gt; &lt;br&gt;the pics are heavy but I didn&amp;#39;t want to spoil them (you&amp;#39;ll see)&lt;br&gt;&lt;br&gt;&lt;br clear="all"&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-6256636650087136800?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/6256636650087136800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=6256636650087136800' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/6256636650087136800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/6256636650087136800'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2007/07/ruby-social-club-night.html' title='Ruby Social Club night'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-367442038448315360</id><published>2007-07-04T11:54:00.001+02:00</published><updated>2007-07-04T11:54:17.120+02:00</updated><title type='text'>Are you still reading me?</title><content type='html'>I haven&amp;#39;t been blogging for a long looong time as I have been busy in a number of other activities.&lt;br&gt;Mainly stuff like giving some balance to my life and making up my mind for the next important steps in my life.&lt;br&gt; &lt;br&gt;Apologies to all people I have not been talking to during these months.&amp;nbsp; It just needed to be done.&lt;br&gt;&lt;br&gt;Now I have to decide if I should go on with this blog, wrap everything up and move somewhere-else which is more representative of who I am now and what I want to do. &lt;br&gt;&lt;br&gt;So.. are you guys still reading my blog?&amp;nbsp; Do I still have some readers? Where are you from, what topics yuo would like me to cover?&lt;br&gt;Please, let me know so that I can take a decision.&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-367442038448315360?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/367442038448315360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=367442038448315360' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/367442038448315360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/367442038448315360'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2007/07/are-you-still-reading-me.html' title='Are you still reading me?'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-116064128515640509</id><published>2006-10-12T10:21:00.000+02:00</published><updated>2007-03-27T20:00:06.180+02:00</updated><title type='text'>TheRubyMine is On</title><content type='html'>Finally we did it!  &lt;a href="http://therubymine.com"&gt;TheRubyMine&lt;/a&gt; is online :-)&lt;br /&gt;The big challenge now is to rally the whole community around it.. any advice on how to build deeper feeling of ownership and participation?&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-116064128515640509?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/116064128515640509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/116064128515640509'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/10/therubymine-is-on.html' title='TheRubyMine is On'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-115740496036795341</id><published>2006-09-04T23:18:00.000+02:00</published><updated>2007-03-27T20:00:54.366+02:00</updated><title type='text'>The Ruby Mine</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5227/1600/1600/logo.0.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/5227/1600/400/logo.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;Whoa! I can't believe we are almost there!!!  It took us a while to get our act together but here it is: &lt;a href="http://www.therubymine.com"&gt;TheRubyMine&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The title is in english, but the content will be Italian, for the guys around here :-)&lt;br /&gt;&lt;br /&gt;We are going to go Beta - invitation only in just a few days..&lt;br /&gt;&lt;br /&gt;Check it out.  Leave your mail.  Join the Vision.&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-115740496036795341?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115740496036795341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115740496036795341'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/09/ruby-mine.html' title='The Ruby Mine'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-115097161681076109</id><published>2006-06-22T12:20:00.000+02:00</published><updated>2006-06-22T12:20:16.903+02:00</updated><title type='text'>NOT Thinking in Java (tm)</title><content type='html'>&lt;span class="gmail_quote"&gt;It has been some time now that I have been thinking about organizing some &lt;/span&gt;&amp;quot;*Not* Thinking in Java (tm)&amp;quot; workshops.&amp;nbsp; It's not that I feel any angst towards Java &lt;span style="font-style: italic;"&gt;  per se&lt;/span&gt;, but attacking Java seems to be the trendy thing to do these days :-)&lt;br&gt; &lt;br&gt; Forget about the Java thing, the sheep-thinking of the object culture is what bothers me.&amp;nbsp; I am not denying my past, since I have also contributed in little part to create it and evangelize it.&amp;nbsp; In the course of the past few years, we have gotten fat with objects and patterns and we have explored the limits of what can be done with objects.&lt;br&gt; &lt;br&gt; That's the way it had to be, but I think that it is now time to explore alternatives.&lt;span class="gmail_quote"&gt;&lt;/span&gt;&amp;nbsp; Lisp, Erlang, Haskell and their friends and cousins.&lt;br&gt; &lt;div&gt; &lt;br&gt; Yesterday I saw a &lt;a href="http://www.defmacro.org/ramblings/fp.html"&gt;nice article on functional languages&lt;/a&gt;.&amp;nbsp; I really liked it.&amp;nbsp; Extremely well written, simple and very pesuasive.&amp;nbsp; Long, but light.&amp;nbsp; I advise eveyone interested in the topic to print it out and read it.&amp;nbsp; It's amazing how things can be different - and difficult things become easy - once you shift your point of view..&lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;/div&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-115097161681076109?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/115097161681076109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=115097161681076109' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115097161681076109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115097161681076109'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/06/not-thinking-in-java-tm.html' title='NOT Thinking in Java (tm)'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-115087702949218503</id><published>2006-06-21T10:03:00.000+02:00</published><updated>2006-06-21T10:03:49.563+02:00</updated><title type='text'>Dojo in Rome</title><content type='html'>My readers will know that we are trying to shake up the italian ruby scene with the Ruby Social Club events.&amp;nbsp; The next meeting in Rome will be hosted by &lt;a href="http://www.interact.it"&gt;Interact&lt;/a&gt; and we will have a proper conference room with projector, network and big screen.&lt;br&gt; &lt;br&gt; We are thinking about some cool new presentation formats to keep everyone active and entertained.. what about the &lt;a href="http://www.theserverside.com/blogs/thread.tss?thread_id=40921"&gt;Dojo&lt;/a&gt;?&lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt;  &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-115087702949218503?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/115087702949218503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=115087702949218503' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115087702949218503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115087702949218503'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/06/dojo-in-rome.html' title='Dojo in Rome'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-115029311713909597</id><published>2006-06-14T15:51:00.000+02:00</published><updated>2006-06-14T15:52:09.153+02:00</updated><title type='text'>Invisible Rails Reference Guide</title><content type='html'>Some of my friends know that I have finally decided to start having a look at Rails.&amp;nbsp; I have found &lt;a href="http://blog.invisible.ch/files/rails-reference-1.1.html"&gt;this fantastic reference guide&lt;/a&gt; by &lt;a href="http://blog.invisible.ch"&gt; InVisible &lt;/a&gt;that seems to answer all my questions!&lt;br clear="all"&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-115029311713909597?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/115029311713909597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=115029311713909597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115029311713909597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/115029311713909597'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/06/invisible-rails-reference-guide.html' title='Invisible Rails Reference Guide'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114925326499162953</id><published>2006-06-02T15:01:00.000+02:00</published><updated>2006-06-02T20:37:53.633+02:00</updated><title type='text'>Javascript programming with MozLab</title><content type='html'>Wait a minute, wasn't javascript a java-like scripting language for browser?  I will not deny that this belief also kept me away from doing any firefox extension development.&lt;br /&gt;&lt;br /&gt;Today I discovered &lt;a href="http://dev.hyperstruct.net/trac/mozlab"&gt; MozLab&lt;/a&gt; and there is no turning back :-)  You can do ubercool development on the mozilla platform with Repl (a kind of Irb on steroids.. you navigate and manipulate live objects inside the browser!!!)  That's enough to tempt the Metaprogrammer in me :-)  Then, of course, you have MozUnit for the TDD and agile minded.&lt;br /&gt;&lt;span class="gmail_quote"&gt;&lt;br /&gt;&lt;/span&gt;I wonder how many other languages are deeply misunderstood out there...&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114925326499162953?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114925326499162953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114925326499162953' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114925326499162953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114925326499162953'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/06/javascript-programming-with-mozlab.html' title='Javascript programming with MozLab'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114785944099953474</id><published>2006-05-17T11:50:00.000+02:00</published><updated>2006-05-17T11:50:41.056+02:00</updated><title type='text'>On Simplicity and Execution</title><content type='html'>I have recently started to use &lt;a href="http://del.icio.us/"&gt;delicious&lt;/a&gt;, the social bookmarking system.&amp;nbsp; Today I also found out about delicious networks: you can subscribe to the delicious feeds of a number of users and then see them as a single unified feed.&amp;nbsp; &lt;br&gt; &lt;br&gt; You can also subscribe to individual RSS feeds and be notified when someone you know and trust comes up with a new interesting link.&lt;br&gt; &lt;br&gt; Why am I talking about this?&amp;nbsp; I started thinking about these delicious features because back in 2000/2001 I was thinking about something quite similar from a philosophical point of view.&amp;nbsp; I wanted to have a way to communicate to a network of trusted people the evolution of my interests and how I was structuring the nformation that I was getting from the internet.&amp;nbsp; I was thinking about a complex trust system, modelled using graph theory.&amp;nbsp; I had pieces of news moving across the graph, gaining strength as they received a thumb-up by more and more users.&lt;br&gt; &lt;br&gt; I was theorizing about the rise of &lt;span style="font-style: italic;"&gt;implicit communities&lt;/span&gt;, ephemeral islands in the net auto-defined by links of mutual trust and common interests.&lt;br&gt; &lt;br&gt; Too much theorizing.&amp;nbsp; There were overwhelming theoretical problems there.&amp;nbsp; How to avoid dangerous trust-feedbacks of information within a network? How should trust be modelled?&amp;nbsp; What are the dimensions of trust?&lt;br&gt; &lt;br&gt; That's all academic bullshit.&amp;nbsp; &lt;br&gt; &lt;br&gt; Useful for after-the-fact analysis.&amp;nbsp; &lt;br&gt; Useless to get started doing things.&lt;br&gt; &lt;br&gt; Everybody can have a good idea.&amp;nbsp; Ideas have become dead cheap.&lt;br&gt; &lt;br&gt; Good executon means getting the simplest idea and get it implemented and used by people.&amp;nbsp; &lt;br&gt; The rest will follow, if it still makes sense.&lt;br clear="all"&gt;&lt;br&gt; I need people to shake me every now and again and tell me: &amp;quot;Yes, it's nice, cool, fantastic! but.. what can we implement and ship right now?&amp;quot;&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114785944099953474?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114785944099953474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114785944099953474' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114785944099953474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114785944099953474'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/on-simplicity-and-execution.html' title='On Simplicity and Execution'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114778626425745491</id><published>2006-05-16T15:31:00.000+02:00</published><updated>2006-05-16T15:31:04.316+02:00</updated><title type='text'>Article for Ruby Code &amp; Style</title><content type='html'>I am planning to write an article for &lt;a href="http://www.artima.com/rubycs"&gt;Ruby Code &amp;amp; Style&lt;/a&gt;, so I ask you, my good readers, what kind of article would you like to see?&lt;br clear="all"&gt;&lt;br&gt; You can answer in the comments or on kiaroskuro AT gmail DOT com.&lt;br&gt; &lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114778626425745491?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114778626425745491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114778626425745491' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114778626425745491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114778626425745491'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/article-for-ruby-code-style.html' title='Article for Ruby Code &amp; Style'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114748232652244578</id><published>2006-05-13T03:05:00.000+02:00</published><updated>2006-05-13T03:05:26.583+02:00</updated><title type='text'>Grady Booch</title><content type='html'>Grady Booch announced on his blog that he has health problems and he is going to undergo surgery in the very near future.&amp;nbsp; Grady Booch has been one of my early software heroes and I remember seeing him at OOPSLA back in '97.&amp;nbsp; I wish him all the best. &lt;br clear="all"&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114748232652244578?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114748232652244578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114748232652244578' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114748232652244578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114748232652244578'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/grady-booch.html' title='Grady Booch'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114730559290381761</id><published>2006-05-11T01:46:00.000+02:00</published><updated>2006-05-11T01:59:52.913+02:00</updated><title type='text'>Burnt Out</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5227/1600/1600/images2.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5227/1600/320/images2.jpg" alt="" border="0" /&gt;&lt;/a&gt;In the course of the past week or so I haven't been very good at answering to people I am in touch with.  I apologize to you all.  I continuously feel very tired and I needed a bit of a break.&lt;br /&gt;&lt;br /&gt;I have been in touch with so many people recently.. being busy talking, planning and organizing that my body could barely catch up with my activities.&lt;br /&gt;&lt;br /&gt;I now start feeling a bit better and I will &lt;span style="font-weight: bold;"&gt;slowly&lt;/span&gt; go back to my coding, networking, book writing, socializing, plotting and planning.  My girlfriend might appreciate some of my time too :-)&lt;br /&gt;&lt;br /&gt;I am afraid that if I want to keep up with this rythm I'll have to take on doing some exercising.  Andrea, a friend of mine, told me that there is a group doing yoga-like practice in the evening in a park just behind the Colosseum.  It sounds good and I might go with him to check it out one of these days.  I have practiced meditation for a while in the past at a Buddhist School in England and I know the value of cultivating a fresh unencumbered centered mind.&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114730559290381761?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114730559290381761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114730559290381761' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114730559290381761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114730559290381761'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/burnt-out.html' title='Burnt Out'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114730414016504689</id><published>2006-05-11T01:35:00.000+02:00</published><updated>2006-05-11T01:35:40.246+02:00</updated><title type='text'>20th of May Padua Presentation</title><content type='html'>It's official.&amp;nbsp; I am going to give a talk about ruby to a great bunch of java coders in &lt;a href="http://www.jugpadova.it/articles/2006/04/30/jug-meeting-28-da-java-a-ruby-e-ritorno"&gt;Padua on the 20th of May&lt;/a&gt;.&lt;br&gt;I feel slightly nervous since it has been a long time since I gave a talk, but I think it's a great opportunity to get back into shape. &lt;br&gt;&lt;br&gt;I am only afraid that 45 minutes might not be enough to do justice to the language...&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114730414016504689?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114730414016504689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114730414016504689' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114730414016504689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114730414016504689'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/20th-of-may-padua-presentation.html' title='20th of May Padua Presentation'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114725240116271708</id><published>2006-05-10T11:13:00.000+02:00</published><updated>2006-05-10T11:16:25.023+02:00</updated><title type='text'>Cyc Space</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5227/1600/1600/cycmap.0.gif"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/5227/1600/400/cycmap.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;A Map of the Cyc universe, from &lt;a href="http://www.opencyc.org/doc/topic_map"&gt;http://www.opencyc.org/doc/topic_map&lt;/a&gt;. &lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114725240116271708?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114725240116271708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114725240116271708' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114725240116271708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114725240116271708'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/cyc-space.html' title='Cyc Space'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114725121243115388</id><published>2006-05-10T10:53:00.000+02:00</published><updated>2006-05-10T10:53:32.476+02:00</updated><title type='text'>OpenCyc Technology - Formalizing Knowledge</title><content type='html'>&lt;div&gt;I have been wanting to blog this for a while now.&amp;nbsp; I should really try to post some of the goodies that I have found on programmable language-resources on the web.&amp;nbsp; I would also like to elicit you guys&amp;nbsp;to point out more sites and libraries, especially if they happen to support a Ruby API :-) &lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;a href="http://www.opencyc.org/"&gt;OpenCyc&lt;/a&gt; is an OSS&amp;nbsp;system that can be used to formalize common sense reasoning within an inference engine.&amp;nbsp; The best thing is the wealth of data that comes with it.&amp;nbsp; &lt;a href="http://www.opencyc.org/doc"&gt; Here&lt;/a&gt; is the documentation, and a brief summary of its &lt;a href="http://www.artima.com/forums/flat.jsp?forum=106&amp;amp;thread=50524"&gt;capabilities&lt;/a&gt;.&lt;br clear="all"&gt;&lt;br&gt;-- &lt;br&gt;&lt;a href="http://liquiddevelopment.blogspot.com"&gt; Chiaroscuro&lt;/a&gt; &lt;/div&gt; &lt;div&gt;&lt;br&gt;&amp;nbsp;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114725121243115388?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114725121243115388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114725121243115388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114725121243115388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114725121243115388'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/opencyc-technology-formalizing.html' title='OpenCyc Technology - Formalizing Knowledge'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114694558546484820</id><published>2006-05-06T21:59:00.000+02:00</published><updated>2006-05-06T21:59:45.470+02:00</updated><title type='text'>Chiaroscuro Radio</title><content type='html'>I was sure I would have never done it.&amp;nbsp; I would have never posted pictures of my cat, or inflicted my poor taste on my readers.&lt;br&gt;&lt;br&gt;Still, it happened.&amp;nbsp; On the sidebar you can now find a link to Chiaroscuro Radio!&lt;br&gt;&lt;br&gt; My musical taste has been defined at different times as:&lt;br&gt;&lt;ul&gt;&lt;li&gt;&amp;quot;it sounds like they are skinning a poor cat&amp;quot;&lt;/li&gt;&lt;li&gt;&amp;quot;gee, they all sound the same&amp;quot;&lt;/li&gt;&lt;li&gt;&amp;quot;how can you like this stuff?&amp;quot; &lt;br&gt;   &lt;/li&gt;&lt;/ul&gt;  Chiaroscuro Radio has been realized using &lt;a href="http://www.pandora.com/"&gt;Pandora&lt;/a&gt;, a software that can learn your musical taste.&amp;nbsp; It took a few days, but now it almost always picks songs that I like.&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114694558546484820?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114694558546484820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114694558546484820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114694558546484820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114694558546484820'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/chiaroscuro-radio.html' title='Chiaroscuro Radio'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114694027448688975</id><published>2006-05-06T20:31:00.000+02:00</published><updated>2006-05-06T20:31:15.553+02:00</updated><title type='text'>Little Boxes in the Spreadsheet</title><content type='html'>Tonight I should make the first release of Littleboxes, a micro-language (API? DSL? Lingo? dunno!) that allows you to use excel as a debugging writeboard from ruby.&lt;br&gt;&lt;br&gt;You will be able to stream out Objects, Structs, Arrays, Strings, Hashes, etc.. to the spreadsheet so that you can better visualize the data you are working on. &lt;br&gt;&lt;br&gt;Is there any feature that might turn out useful to you?&amp;nbsp; I have still got the evening to work on it before releasing the alpha version to the italian ruby community.&amp;nbsp; If you are not on the ruby-it mailing list drop me an email (kiaroskuro AT gmail DOT com) or a comment and I'll send it to you too. &lt;br&gt;&lt;br&gt;In the meantime I'll leave you with some words from Littleboxes, a classic by Malvina Reynolds..&lt;br&gt; &lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-style: italic;"&gt;&amp;quot;Little boxes on the hillside,&lt;/span&gt;&lt;br style="font-style: italic;"&gt;    &lt;span style="font-style: italic;"&gt;Little boxes made of ticky tacky&lt;/span&gt;&lt;br style="font-style: italic;"&gt;   &lt;span style="font-style: italic;"&gt;Little &amp;nbsp;boxes on the hillside,&lt;/span&gt;&lt;br style="font-style: italic;"&gt;   &lt;span style="font-style: italic;"&gt;Little boxes all the same,&lt;/span&gt;&lt;br style="font-style: italic;"&gt;   &lt;span style="font-style: italic;"&gt;There's a green one and &amp;nbsp;a pink one&lt;/span&gt;&lt;br style="font-style: italic;"&gt;   &lt;span style="font-style: italic;"&gt;And a blue one and a yellow one&lt;/span&gt;&lt;br style="font-style: italic;"&gt;   &lt;span style="font-style: italic;"&gt;And they're all made out of &amp;nbsp;ticky tacky&lt;/span&gt;&lt;br style="font-style: italic;"&gt;   &lt;span style="font-style: italic;"&gt;And they all look just the same.&amp;quot;&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt; &lt;br&gt;and no, Malvina is not talking about Excel cells ;-)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114694027448688975?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114694027448688975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114694027448688975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114694027448688975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114694027448688975'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/little-boxes-in-spreadsheet.html' title='Little Boxes in the Spreadsheet'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114686943512369821</id><published>2006-05-06T00:50:00.000+02:00</published><updated>2006-05-06T00:50:35.130+02:00</updated><title type='text'>Refactoring Emphasis in Language</title><content type='html'>Language is one of the most ancient forms of knowledge encoding and transmission, yet we have so little conscious knowledge of how we can use it to achieve the communication that we want.&lt;br&gt;&lt;div align="justify"&gt;&lt;br&gt;Words are programs, psychoglyphs running into other people's head. Shaping words means shaping active executable knowledge.&lt;br&gt;&lt;br&gt;While reading &amp;quot; &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0916990435/103-8458819-7646237?v=glance"&gt;sleight of mouth&lt;/a&gt;&amp;quot; by &lt;a href="http://www.nlpu.com/"&gt;Robert Dilts&lt;/a&gt;, I found a couple of very interesting concepts. &lt;br&gt;&lt;br&gt;Look at the following sentences and feel the difference, although they have the same informational contant at face value:&lt;br&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;I want to do X, but I have a problem&lt;/li&gt;&lt;li&gt;I want to do X, and I have a problem &lt;/li&gt;&lt;li&gt;I want to do X, even if I have a problem&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I call &amp;quot;But&amp;quot;, &amp;quot;and&amp;quot; and &amp;quot;even if&amp;quot; &lt;em&gt;&lt;strong&gt;Emphatic Tags&lt;/strong&gt;&lt;/em&gt; and they can be used to move the emphasis between:&lt;/p&gt;&lt;ul&gt; &lt;li&gt;justification, passive stance&lt;/li&gt;&lt;li&gt;equanimity, objective stance&lt;/li&gt;&lt;li&gt;drive, propositive stance&lt;/li&gt;&lt;/ul&gt;&lt;p align="justify"&gt;You can do a little word magick by restating sentences, while refactoring it for an emphatic change, and throwing them back with a more empowered meaning, &lt;em&gt;even if&lt;/em&gt; you have never tried before.&lt;/p&gt;&lt;p&gt;The other emphasis trick is the enabler/toll stance.&lt;/p&gt;&lt;p align="justify"&gt;Read the following and feel the different emotional effect in front of apparently identical information: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;If you feel like putting some effort in it, you can do anything you want&lt;/li&gt;&lt;li&gt;You can do anything you want, if you feel like putting some effort in it &lt;/li&gt;&lt;/ul&gt;&lt;p align="justify"&gt;The sentence order makes a world of difference. The first part of the sentence sets the context, while the second part clarifies the meaning of the first one.&lt;/p&gt;&lt;p align="justify"&gt;The if-opening sentence is a &lt;strong&gt;&lt;em&gt;Toll Sentence&lt;/em&gt;&lt;/strong&gt;. It's asking you for something, for a precondition, before giving you what you want. It's even hinting at the fact that you are not doing what is necessary. It feels like you are trying to convince someone of something.&lt;/p&gt;&lt;p align="justify"&gt;The you-can-opening sentence is an &lt;strong&gt;&lt;em&gt;Enabler Sentence&lt;/em&gt;&lt;/strong&gt;. It offers you a wide range of options: &lt;em&gt;anything you want&lt;/em&gt;, and it then points to the path to go and grab those options. &lt;/p&gt;&lt;p align="justify"&gt;&lt;br&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114686943512369821?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114686943512369821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114686943512369821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114686943512369821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114686943512369821'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/refactoring-emphasis-in-language.html' title='Refactoring Emphasis in Language'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114677176266079314</id><published>2006-05-04T21:42:00.000+02:00</published><updated>2006-05-04T21:42:43.460+02:00</updated><title type='text'>Executable Knowledge</title><content type='html'>&lt;a href="http://riffraff.blogsome.com/2006/05/04/organizzare-la-conoscenza/"&gt;Gabriele&lt;/a&gt; is quoting from an &lt;a href="http://www.ecologiadeisitiweb.net/interviste/organizzare-la-conoscenza-intervista-a-luca-rosati"&gt;interview &lt;/a&gt; to Luca Rosati (in italian):&lt;br&gt; &lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p&gt;I realized that too many time we 'reinvent the wheel'.&amp;nbsp; More mature disciplines - such as biblioteconomy, but also psycholinguistics and neurosciences - have found a way to deal with this problem several decades ago... &lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;I have to say that I haven't read the interview yet, but I am still going to comment on this quote.&lt;br&gt;&lt;br&gt;It's common to hear people complaining about how Computer Science is immature compared to other disciplines, but I don't sympathise with this point of view.&amp;nbsp; Other disciplines organise knowledge within a specific domain, whereas the domain of software development is the very act of organising knowledge!&amp;nbsp; Executable knowledge, make no mistake, but still knowledge. &lt;br&gt;&lt;br&gt;If you see things from this point of view, software development is a reflective meta-discipline.&amp;nbsp; It's part of the very core of software development to change itself, its own tools, the way it models itself and the rest of the world.&amp;nbsp; The discipline keeps changing because it's an highly introspective discipline, more similar to literature in this respect than to engineering.&amp;nbsp; It is a discipline that talks about the world, but that mainly likes to talk about itself to reflect, evolve and change. &lt;br&gt;&lt;br&gt;Software development changes as the world changes, because the way we see the world and organise our knowledge does change.&amp;nbsp; I would find it worrying if it didn't.&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114677176266079314?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114677176266079314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114677176266079314' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114677176266079314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114677176266079314'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/executable-knowledge.html' title='Executable Knowledge'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114661226533670468</id><published>2006-05-03T01:24:00.000+02:00</published><updated>2006-05-03T01:24:25.413+02:00</updated><title type='text'>Good Hungarian</title><content type='html'>&lt;font size="2"&gt;&lt;span id="st" name="st" class="st"&gt;We are used to think of hungarian notation as being a bad thing.&amp;nbsp; However, not many people know that what we know as hungarian notation is a perverted version of the original pure and good hungarian notation.&amp;nbsp; Joel Spolsky  &lt;a href="http://www.joelonsoftware.com/articles/Wrong.html"&gt;talks about that&lt;/a&gt; too.&lt;br&gt;&lt;br&gt;Bad&lt;/span&gt;-&lt;span id="st" name="st" class="st"&gt;hungarian&lt;/span&gt; is when you prefix a variable name with type information&lt;br&gt;&lt;br&gt;eg: &lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;font size="2"&gt;&amp;nbsp; fWidth = fSize&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;font size="2"&gt;&lt;br&gt;the 'f' simply means float.&amp;nbsp; &lt;br&gt;&lt;br&gt;You can see you have type compatibilty on both sides, but it doesn't say anything about semantic compatibility. fWidth could be used as a measure expressed in metres, whereas fSize is expressed in feet! &lt;br&gt;&lt;br&gt;&lt;span id="st" name="st" class="st"&gt;Good&lt;/span&gt;-&lt;span id="st" name="st" class="st"&gt;hungarian&lt;/span&gt; is when you prefix a variable name with semantic information&lt;br&gt;&lt;br&gt;&lt;/font&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp; mtrWidth = ftSize&lt;br&gt; &lt;br&gt;OR&lt;br&gt;&lt;br&gt; &lt;/font&gt;&lt;font size="2"&gt;&amp;nbsp;&amp;nbsp; metric_width = feet_size&lt;br&gt;&lt;br&gt;you can see immediately that there is a problem there.&amp;nbsp; &lt;br&gt;&lt;br&gt;Both variables are of the same type (Float), yet they have a different meaning.&amp;nbsp; The prefix difference make the error stand out clearly.&lt;br&gt;&lt;br&gt;This is very useful in general, but I would argue that in ruby - with the dynamism offered by duck typing - good hungarian is very useful and we already use, without even thinking about it. &lt;br clear="all"&gt;&lt;br&gt;&lt;/font&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114661226533670468?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114661226533670468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114661226533670468' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114661226533670468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114661226533670468'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/good-hungarian.html' title='Good Hungarian'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114660382144858232</id><published>2006-05-02T23:03:00.000+02:00</published><updated>2006-05-02T23:03:41.493+02:00</updated><title type='text'>Metaprogramming your Breakfast</title><content type='html'>Following on from the &lt;a href="http://liquiddevelopment.blogspot.com/2006/04/way-of-meta-part-iv-hijacking-local.html"&gt;metaprogramming breakfast&lt;/a&gt;, I think someone is meta-challenging me &lt;a href="http://riffraff.blogsome.com/2006/05/02/metaprogramming-breakfast/"&gt; here&lt;/a&gt; :-)&lt;br clear="all"&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114660382144858232?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114660382144858232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114660382144858232' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114660382144858232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114660382144858232'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/05/metaprogramming-your-breakfast.html' title='Metaprogramming your Breakfast'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114631722061726022</id><published>2006-04-29T15:27:00.000+02:00</published><updated>2006-04-29T15:27:01.563+02:00</updated><title type='text'>Twisting and Shaping DSLs using Ruby Metaprogramming</title><content type='html'>I write this in response to Federico Feroldi's comment to &lt;a href="http://liquiddevelopment.blogspot.com/2006/04/way-of-meta-part-iv-hijacking-local.html"&gt;my previous post on defining simple DSLs&lt;/a&gt;.&lt;br clear="all"&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; font-style: italic; color: rgb(102, 0, 204);" class="gmail_quote"&gt; &lt;span style="color: rgb(102, 102, 102);"&gt;[..] while reading your article I was thinking about using the recipe name string as an object to route the messages coming from the ingredients and then catching them by implementing missing_method in the string object... &lt;/span&gt;&lt;br style="color: rgb(102, 102, 102);"&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;So, for:&lt;/span&gt;&lt;br style="color: rgb(102, 102, 102);"&gt;&lt;br style="color: rgb(102, 102, 102);"&gt; &lt;span style="color: rgb(102, 102, 102);"&gt;recipe &amp;quot;italian breakfast&amp;quot; do&lt;/span&gt;&lt;br style="color: rgb(102, 102, 102);"&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;nbsp;&amp;nbsp;  caffe = 1, :macchiato&lt;/span&gt;&lt;br style="color: rgb(102, 102, 102);"&gt; &lt;span style="color: rgb(102, 102, 102);"&gt;end&lt;/span&gt;&lt;br style="color: rgb(102, 102, 102);"&gt;&lt;br style="color: rgb(102, 102, 102);"&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;is there a way to translate it into:&lt;/span&gt;&lt;br style="color: rgb(102, 102, 102);"&gt; &lt;br style="color: rgb(102, 102, 102);"&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;&amp;quot;italian breakfast&amp;quot;.caffe(1, :macchiato) ?&lt;/span&gt;&lt;br style="color: rgb(102, 102, 102);"&gt;&lt;span style="color: rgb(102, 102, 102);"&gt;[..] &lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;Let's see:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt; &amp;quot;italian breakfast&amp;quot;.caffe 1, :macchiato&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;First of all, I removed the brackets because I don't believe in brackets :-)&lt;br&gt;&lt;br&gt;What Federico proposes can be done, but I am not sure I would do it this way, unless I am working&amp;nbsp;  &lt;span style="font-weight: bold;"&gt;only &lt;/span&gt;within the context of a DSL.&amp;nbsp; If you want your recipe-string to accept the &lt;span style="font-style: italic;"&gt;caffe&lt;/span&gt; method, then you have to override the &lt;span style="font-style: italic;"&gt; method_missing&lt;/span&gt; method of the String class, which can be a dangerous thing to do if you have loaded other meta-code that overrides this method on a String or Object level. &lt;br&gt;&lt;br&gt;I would rather go for a &lt;span style="font-weight: bold;"&gt; Concept Wrap Up&lt;/span&gt;: &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &lt;span style="font-weight: bold;"&gt;Recipe&lt;/span&gt;(&amp;quot;italian breakfast&amp;quot;).caffe&amp;nbsp; 1, :macchiato&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/blockquote&gt;&lt;br&gt;where I make explicit the meaning of 'italian breakfast' by wrapping it into a Recipe object.&amp;nbsp; Note that I did not use Recipe. &lt;span style="font-style: italic;"&gt;new&lt;/span&gt;.&amp;nbsp; I am launching a campaign against the use of &lt;span style="font-style: italic;"&gt;new&lt;/span&gt; in application code, which I consider at the same level of badly used hungarian notation (because  &lt;span style="font-weight: bold;"&gt;there is&lt;/span&gt; such a thing as &lt;a href="http://www.joelonsoftware.com/articles/Wrong.html"&gt;good hungarian notation&lt;/a&gt;).&lt;br&gt;&lt;br&gt;Another way I would do it is by using what I call a &lt;span style="font-weight: bold;"&gt; Conjunction&lt;/span&gt;:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt; &amp;quot;italian breakfast&amp;quot;.&lt;span style="font-weight: bold;"&gt;consists_of&lt;/span&gt;.caffe&amp;nbsp; 1, :macchiato&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;You will have to inject a &lt;span style="font-style: italic;"&gt;consists_of&lt;/span&gt; method in the String class, which will act as a conjunction between the String and the method call.&amp;nbsp; The conjunction will take the String and wrap it up in a Recipe object.&amp;nbsp; The cafe method is then invoked on the Recipe object. &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;In both cases we have moved the handling of the &lt;span style="font-style: italic;"&gt;method_missing&lt;/span&gt; from String to a custom made Recipe class.&lt;br&gt;&lt;br&gt;The conjunction will be:&lt;br&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; font-family: courier new,monospace;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; class&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: blue;"&gt;String&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 9pt; color: rgb(0, 127, 0);"&gt;#Recipe conjuction&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;consists_of &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Recipe &lt;b&gt;.&lt;/b&gt;new&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;self&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt; &lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/blockquote&gt;        &lt;br&gt;The Recipe will start as:&lt;br&gt;&lt;br&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; class&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: blue;"&gt;Recipe&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt; initialize&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;recipe_name&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(176, 0, 128);"&gt;@name&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;recipe_name&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(176, 0, 128);"&gt;@ingredients&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;{}&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;register_with_global_repository&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&amp;nbsp;&lt;span style=""&gt; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt; method_missing&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;method&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; *&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;args&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(176, 0, 128);"&gt;@ingredients&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;method&lt;b&gt; .&lt;/b&gt;to_s&lt;b&gt;]&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt; args&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; end&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br style="font-family: courier new,monospace;"&gt;&lt;/blockquote&gt;                      &lt;br&gt;The method_missing is catching the ingredients and it stacks them nicely on an hashtable.&amp;nbsp; Why do we need the &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt; register_with_global_repository call, though?&lt;br&gt;&lt;br&gt;Since we are working with a DSL and we are not explicitly storing a reference to a created recipes in a variable, then we get the Recipe to self-register itself with a global centralized repository.&amp;nbsp; I could have made it a  &lt;span style="font-style: italic;"&gt;@@all_recipes&lt;/span&gt; class attribute, but I think that in this simple example it looks clearer as an external separate entity:&lt;br&gt;&lt;br&gt;&lt;/span&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: purple; font-family: Verdana;"&gt; $RECIPES_REPOSITORY&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black; font-family: Verdana;"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black; font-family: Verdana;"&gt;{}&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;class&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: blue; font-family: Verdana;"&gt; Recipe&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: blue; font-family: Verdana;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;…&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black; font-family: Verdana;"&gt;private&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127); font-family: Verdana;"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127); font-family: Verdana;"&gt; register_with_global_repository&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt;&lt;span style=""&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: purple; font-family: Verdana;"&gt;$RECIPES_REPOSITORY&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black; font-family: Verdana;"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: rgb(176, 0, 128); font-family: Verdana;"&gt; @name&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black; font-family: Verdana;"&gt;]&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black; font-family: Verdana;"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127); font-family: Verdana;"&gt;self&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127); font-family: Verdana;"&gt;end&lt;/span&gt; &lt;/b&gt;&lt;span style="font-size: 10pt; color: gray; font-family: Verdana;"&gt;&lt;span style=""&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127); font-family: Verdana;"&gt;end&lt;/span&gt; &lt;/b&gt;&lt;/p&gt;&lt;/blockquote&gt;                    and finally the code to print out the recipe:&lt;br&gt;&lt;br&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt; class&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: blue;"&gt;Recipe&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: blue;"&gt; &lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;…&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt; def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 127, 127);"&gt;report&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;puts&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(127, 0, 127);"&gt;&amp;quot;to make #{@name} you should buy:&amp;quot;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; &lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(176, 0, 128);"&gt;@ingredients.each_pair&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt; do&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; &lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;|&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;ingredient&lt;b&gt;,&lt;/b&gt;description&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;puts&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(127, 0, 127);"&gt;&amp;quot; * #{Array(description).join ' '} #{ingredient}&amp;quot;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt; &lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;…&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt; end&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/blockquote&gt;                          &lt;br&gt;&lt;span style="font-size: 10pt; color: black;"&gt;What is still missing is a method to print out the recipe directly from the DSL.&amp;nbsp; We would like our call to look like this:&lt;br&gt;&lt;/span&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; font-family: courier new,monospace;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt; recipe?&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(127, 0, 127);"&gt;&amp;quot;italian breakfast&amp;quot;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;  &lt;br&gt;This snippet fully satisfies our language choice:&lt;br&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;recipe?&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt; recipe_name&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: purple;"&gt; $RECIPES_REPOSITORY&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;recipe_name&lt;b&gt;].&lt;/b&gt;report&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt; &lt;b style="font-family: courier new,monospace;"&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;      Our new DSL now allows us to write:&lt;br&gt;&lt;br&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;span style="font-size: 10pt; color: rgb(127, 0, 127);"&gt; &amp;quot;italian breakfast&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;consists_of&lt;b&gt;.&lt;/b&gt;caffe&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;1&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(192, 160, 48);"&gt; :macchiato&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: courier new,monospace; color: black;"&gt;recipe?&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: courier new,monospace; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; font-family: courier new,monospace; color: rgb(127, 0, 127);"&gt;&amp;quot;italian breakfast&amp;quot;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;    and to obtain:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;to make italian breakfast you should buy: &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 1 macchiato caffe&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;The one big limitation is that at the moment you can define recipes with only one ingredient.&lt;br&gt; &lt;br&gt;We get around this limitation by making the &lt;span style="font-style: italic;"&gt;method_missing&lt;/span&gt; a &lt;span style="font-weight: bold;"&gt;Follow Up Method Chain&lt;/span&gt;:&lt;br&gt;&lt;br&gt;    &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 127, 127);"&gt; allow_method_chaining&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;()&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt; self&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt; &lt;br&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;p class="MsoNormal" style=""&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 127, 127);"&gt; method_missing&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;method&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;*&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;args&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(176, 0, 128);"&gt;@ingredients &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;method&lt;b&gt;.&lt;/b&gt;to_s&lt;b&gt;]&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt; args&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: black;"&gt; allow_method_chaining&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; font-family: Verdana; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;          The trick here is that after having defined an ingredients we still have the original Recipe object ready to accept new ingredients.&lt;br&gt;&lt;span style="font-size: 10pt; color: black;"&gt;&lt;br&gt;You can now do:&lt;br&gt;&lt;br&gt;&lt;/span&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; font-family: courier new,monospace;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: rgb(127, 0, 127);"&gt; &amp;quot;italian breakfast&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;.&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;consists_of&lt;b&gt;.&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;caffe&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;1&lt;/span&gt; &lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(192, 160, 48);"&gt;:macchiato&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; ).&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;" lang="IT"&gt; cornetto&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);" lang="IT"&gt;1&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;" lang="IT"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;" lang="IT"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(192, 160, 48);" lang="IT"&gt;:cioccolato&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;" lang="IT"&gt;)&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;" lang="IT"&gt;&lt;/span&gt; &lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: gray;" lang="IT"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;" lang="IT"&gt;recipe?&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;" lang="IT"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(127, 0, 127);" lang="IT"&gt;&amp;quot;italian breakfast&amp;quot;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;" lang="IT"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;          &lt;br&gt;&lt;span style="font-size: 10pt; color: black;"&gt;and get:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-size: 10pt; color: rgb(0, 153, 0);"&gt; to make italian breakfast you should buy:&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="font-size: 10pt; color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 1 cioccolato cornetto&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="font-size: 10pt; color: rgb(0, 153, 0);"&gt; &amp;nbsp;* 1 macchiato caffe&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 10pt; color: black;"&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size: 10pt; color: black;"&gt;&lt;br&gt;&lt;br&gt;That was long! I think I will now go for a &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; 1 cioccolato cornetto&lt;/span&gt;!&lt;br&gt;&lt;br&gt;&lt;/span&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114631722061726022?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114631722061726022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114631722061726022' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114631722061726022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114631722061726022'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/twisting-and-shaping-dsls-using-ruby.html' title='Twisting and Shaping DSLs using Ruby Metaprogramming'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114625499134771919</id><published>2006-04-28T22:09:00.000+02:00</published><updated>2006-04-28T22:09:51.396+02:00</updated><title type='text'>The Way of Meta - Part IV - Hijacking Local Variables in DSLs</title><content type='html'>&lt;p class="MsoNormal" style="margin: 0cm 0cm 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 18pt; font-family: 'Comic Sans MS';" lang="EN-GB"&gt;The Way of &lt;/span&gt;&lt;span style="font-size: 18pt; font-family: 'Comic Sans MS';" lang="EN-GB"&gt;  Meta&lt;/span&gt;&lt;span style="font-size: 18pt; font-family: 'Comic Sans MS';" lang="EN-GB"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin: 0cm 0cm 6pt; text-align: center;" align="center"&gt;&lt;span style="font-family: 'Comic Sans MS';"&gt; ~&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="margin: 0cm 0cm 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 10pt; font-family: 'Comic Sans MS';" lang="EN-GB"&gt;V. 0.0.4&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin: 0cm 0cm 6pt; text-align: center;" align="center"&gt; &lt;span style="font-size: 10pt; font-family: 'Comic Sans MS';" lang="EN-GB"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;Not long ago I have read the '&lt;a href="http://www.artima.com/rubycs/articles/ruby_as_dsl.html"&gt;Creating DSLs with Ruby&lt;/a&gt;' article written by Jim Freeze, where he explains how to forge a  &lt;a href="http://www.oreillynet.com/ruby/blog/2005/12/what_is_a_dsl.html"&gt;DSL&lt;/a&gt; step by step, creating a new human readable formalism on top of ruby.&amp;nbsp; I really enjoyed the article as it went along some of the lines of thought that I have been working on for a while. &lt;br&gt;&lt;br&gt;In the article there was a point that was left somewhat open: how to allow developers using a DSL to assign values to new concepts that they define on the spot, and then get access to both these concepts and their values from within the DSL. &lt;br&gt;&lt;br&gt;I realize I have been a bit vague here, so I'll give you a straightforward example.&amp;nbsp; Let's say we want to define a DSL to describe the shopping list with all the ingredients needed to make a certain recipe..&lt;br&gt;&lt;br&gt; Ideally we would like to write something like:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt; shopping_list_for &amp;quot;BLT sandwiches for the picnic&amp;quot; do&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; sliced_bread = 3 &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; lettuce = 2&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; tomatoes = 6, :red&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt; &amp;nbsp; bacon = 4&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;end&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;The do..end block delimits a block context that gets passed directly to the  &lt;span style="color: rgb(0, 0, 153);"&gt;shopping_list_for&lt;/span&gt; method.&lt;br&gt;This method should then extract the various ingredients and their quantity and description.&lt;br&gt;&lt;br&gt;How can it do that?&amp;nbsp; One way is to run the block within a context where those ingredients already exist as methods.&amp;nbsp; This context would be a class with -for example- the  &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;sliced_bread=&lt;/span&gt; method overridden to accept the DSL input.&lt;br&gt;&lt;br&gt;What about new ingredients that have not been specified &lt;span style="font-style: italic;"&gt; a priori&lt;/span&gt; ?&amp;nbsp; Your metaprogramming instincts will tell you to go for a method_missing based technique.&amp;nbsp; Wrong.&amp;nbsp; Unless you specify a self (or other object) in front of &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt; sliced_bread&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;/span&gt;, ruby will simply assume that it is a local variable rather than a missing method.&amp;nbsp; Highly annoying if you ask me, but it is necessary to avoid even worst problems and ambiguities when dealing with stuff like mixins. &lt;br&gt;&lt;br&gt;You are left with these three choices:&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;shopping_list_for &amp;quot;BLT sandwiches for the picnic&amp;quot; do &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; self.sliced_bread = 3&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; self.lettuce = 2&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; self.tomatoes = 6, :red&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; self.bacon = 4&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;end&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt; &lt;br&gt;Argh!&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;shopping_list_for &amp;quot;BLT sandwiches for the picnic&amp;quot; do |recipe| &lt;/span&gt; &lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; recipe.sliced_bread = 3&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;recipe.&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt; lettuce = 2&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;recipe.&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt; tomatoes = 6, :red&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;recipe.&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt; bacon = 4&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;end&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt; &lt;br&gt;Just a tad annoying&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;shopping_list_for &amp;quot;BLT sandwiches for the picnic&amp;quot; do &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; @sliced_bread = 3&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; @lettuce = 2&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; @tomatoes = 6, :red&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; @bacon = 4&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;end&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt; &lt;br&gt;The best so far.. you can visualize the @ as bullet points ant it is &lt;span style="font-style: italic;"&gt;kind of&lt;/span&gt; ok.. &lt;br&gt;Kind of.&lt;br&gt;&lt;br&gt;Jim, at this point, proposes to drop the equal sign to force ruby to recognize the new keyword as a method that gets routed through method_missing. &lt;br&gt;&lt;br&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;shopping_list_for &amp;quot;BLT sandwiches for the picnic&amp;quot; do &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; sliced_bread 3&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; lettuce 2&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; tomatoes 6, :red&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; bacon 4&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;end&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt;  &lt;br&gt;I'll admit it, this is not bad at all.&amp;nbsp; Yet it annoys me to no end that I cannot just get those variables that I need from another context.&lt;br&gt;&lt;br&gt;Thinking about there is a way to get variables, and that is the &lt;span style="font-style: italic;"&gt; local_variables&lt;/span&gt; method, but you have to execute it within a specific context.&amp;nbsp; There is also a method to pass around contexts, and that is &lt;span style="font-style: italic;"&gt;binding&lt;/span&gt;.&amp;nbsp; What we have to do is to get the binding of the block and to get the local variables within the context underlying the binding. &lt;br&gt;&lt;br&gt;I tried to call the block and then get the binding of the block, but it didn't work.&amp;nbsp; The block gets executed and the variables fall out of scope and become unavailable.&amp;nbsp; &lt;br&gt;&lt;br&gt;I had to get the block itself to return the binding.&amp;nbsp; This can be done and it works, but the binding looks totally out of place.. &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;shopping_list_for &amp;quot;BLT sandwiches for the picnic&amp;quot; do &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; sliced_bread = 3&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; lettuce = 2&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; tomatoes = 6, :red&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; bacon = 4&lt;/span&gt;&amp;nbsp; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; &lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; binding&lt;/span&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;end&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt; &lt;br&gt;Here it hit me that I could alias the word &lt;span style="font-style: italic;"&gt;binding&lt;/span&gt; to something that would look good with end.&amp;nbsp; What about &lt;span style="font-style: italic;"&gt;the end&lt;/span&gt; ?&amp;nbsp; I know it's tacky, but in its own tacky way it works and sounds credible: &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;shopping_list_for &amp;quot;BLT sandwiches for the picnic&amp;quot; do &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; sliced_bread = 3&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; lettuce = 2&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; tomatoes = 6, :red&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;&amp;nbsp; bacon = 4&lt;/span&gt;&amp;nbsp; &lt;br&gt; &lt;/blockquote&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 0, 153);"&gt;the end&lt;/span&gt;&lt;br&gt;  &lt;/blockquote&gt;  &lt;br&gt;This is the code that allows the DSL to work and to print out the shopping list:&lt;br&gt;&lt;br&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; def&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;report&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt; recipe&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;ingredients&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;puts&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 9pt; color: rgb(127, 0, 127);"&gt; &amp;quot;to make #{recipe} you should buy:&amp;quot;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;ingredients&lt;b&gt;.&lt;/b&gt;each_pair&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; do&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;|&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;ingredient&lt;b&gt;,&lt;/b&gt;description&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt; &lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;puts&lt;/span&gt; &lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 9pt; color: rgb(127, 0, 127);"&gt;&amp;quot; * #{Array(description).join ' '} #{ingredient}&amp;quot;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt; &lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;puts&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;br&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;def &lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;shopping_list&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt; recipe&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;shopping_binding&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;yield&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;ingredients&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;{}&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;eval&lt;b&gt;(&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 9pt; color: rgb(127, 0, 127);"&gt;&amp;quot;local_variables&amp;quot; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;shopping_binding&lt;b&gt;).&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;each &lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;do&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; |&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;var&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;ingredients&lt;b&gt;[&lt;/b&gt;var&lt;b&gt;]&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;=&lt;/span&gt; &lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;eval&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 9pt; color: rgb(127, 0, 127);"&gt;&amp;quot;#{var}&amp;quot; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;shopping_binding&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt; end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;report&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;recipe&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;ingredients&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt; &lt;span style="font-size: 10pt; color: gray;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;alias&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;the&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;binding&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;br&gt; &amp;nbsp;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: black;"&gt;shopping_list&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 9pt; color: rgb(127, 0, 127);"&gt; &amp;quot;english breakfast&amp;quot;&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;do&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;tomatoes&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;2&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(192, 160, 48);"&gt;:green&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;sausages&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;3&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;eggs&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;2&lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(192, 160, 48);"&gt; :big&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;bacon&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt;=&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;  &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;4&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt;&lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: black;"&gt; the&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;blockquote&gt;&amp;nbsp;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: black;"&gt;shopping_list&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 9pt; color: rgb(127, 0, 127);"&gt;&amp;quot;banana milkshake&amp;quot;&lt;/span&gt; &lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;do&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;milk&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;1&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 10pt; color: black;"&gt;bananas&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: black;"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;span style="font-size: 10pt; color: rgb(0, 127, 127);"&gt;2&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="font-family: courier new,monospace;"&gt; &lt;font size="1"&gt;&lt;span style="font-size: 10pt; color: black;"&gt;the&lt;/span&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="font-size: 10pt; color: rgb(0, 0, 127);"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="font-size: 10pt; color: gray;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;                                                                              &lt;br&gt;When you run it you get:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;to make english breakfast you should buy: &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 2 green tomatoes&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 3 sausages&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 4 bacon&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 2 big eggs&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; to make banana milkshake you should buy:&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 2 bananas&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;* 1 milk&lt;/span&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114625499134771919?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114625499134771919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114625499134771919' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114625499134771919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114625499134771919'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/way-of-meta-part-iv-hijacking-local.html' title='The Way of Meta - Part IV - Hijacking Local Variables in DSLs'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114608505354166666</id><published>2006-04-26T22:57:00.000+02:00</published><updated>2006-04-26T22:57:33.616+02:00</updated><title type='text'>Pandora Music Genome</title><content type='html'>Wow! That's all I can say, make sure you check this out:&lt;a href="http://pandora.com/"&gt; Pandora&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It models what you like in  music and makes very very sensible suggestions.&lt;br /&gt;&lt;br /&gt;For example I like mellow rock with female vocal-centric aesthetics in minor key tonalities!  Now I know what to answer when I am asked what music I like!&lt;br /&gt;&lt;br /&gt;This Pandora thing is scary scary..&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114608505354166666?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114608505354166666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114608505354166666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114608505354166666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114608505354166666'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/pandora-music-genome.html' title='Pandora Music Genome'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114604198104647527</id><published>2006-04-26T10:59:00.000+02:00</published><updated>2006-04-26T10:59:41.050+02:00</updated><title type='text'>Ruby for Javists Presentation</title><content type='html'>I am scheduled to give a 40mins presentation on Ruby to a group of javists (both standard edition and enterprise guys :-)&lt;br clear="all"&gt;&lt;br&gt; Do you have any advice on how to present it and what to show them?&lt;br&gt; &lt;br&gt; I am not going to do the &lt;span style="font-style: italic;"&gt;Ruby is Better than Java&lt;/span&gt; number, since that would feel offensive, but I would like to make them want to have a taste of ruby... I would like them to leave with a desire to explore new things.&lt;br&gt; &lt;br&gt; Any advice is well appreciated!&lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt; &lt;br&gt;  &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114604198104647527?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114604198104647527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114604198104647527' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114604198104647527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114604198104647527'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/ruby-for-javists-presentation.html' title='Ruby for Javists Presentation'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114496921496249855</id><published>2006-04-14T00:30:00.000+02:00</published><updated>2006-04-14T01:00:15.053+02:00</updated><title type='text'>Software Superheroes</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5227/1600/1600/story.superheroes.0.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/5227/1600/200/story.superheroes.jpg" alt="" border="0" /&gt;&lt;/a&gt;If there is one great thing about developing software is that software is probably one of the very few professions out there where you can be an awe inspiring &lt;span style="font-weight: bold; font-style: italic;"&gt;Superhero&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Imagine if you were digging holes, moving rocks or filling in papers.  How much difference would  your skill make? You could perform maybe twice, three times better than an average worker.  That's wholesome and fine, but how does it compare to superheroic feats such as flipping cars, vaporising enemies and flying at mach3?&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Well, in software you can be that kind of superhero.   Every improvement that you make, every skill that you learn, allows you to write better software and to handle greater complexity.  If you can handle complexity you can build intellectual augmentations that are like a small army of cybernetic agents working for you.  You harness the power of your skill and your agents, you simplify and organize and you move towards even greater levels of complexity.. that you can handle using abstractions.  Your relative effectiveness is moving along an exponential curve by leveraging the previous software layers.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;If you are a hotshot ruby programmer with a mastery of metaprogramming and you do dynamic programming con gusto, then you can take on a small IT department.  Compared to a dozen of mediocre ASP programmers that copy and paste queries inside html code you are like a small determined hitech army.  They won't even have the time to react.  You are too fast for them.  You do things they don't even comprehend.  Sometimes they don't even understand that you are doing anything at all!&lt;br /&gt;&lt;br /&gt;It's fun to be a superhero in the software world&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;(image by Chip Kidd)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114496921496249855?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114496921496249855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114496921496249855' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114496921496249855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114496921496249855'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/software-superheroes.html' title='Software Superheroes'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114488824324874379</id><published>2006-04-13T02:30:00.000+02:00</published><updated>2006-04-13T02:30:43.360+02:00</updated><title type='text'>Lisp, the 'Why' way</title><content type='html'>I can't believe I &lt;a href="http://www.lisperati.com/casting.html"&gt;found this&lt;/a&gt;.  This is a comic book guide to lisp in a whyesque style.  Great way to get started.&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114488824324874379?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114488824324874379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114488824324874379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114488824324874379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114488824324874379'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/lisp-why-way.html' title='Lisp, the &apos;Why&apos; way'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114484166593058627</id><published>2006-04-12T13:34:00.000+02:00</published><updated>2006-04-12T13:34:26.956+02:00</updated><title type='text'>CodeSushi: Covering the Italian Scene</title><content type='html'>Staring from today my CodeSushi blog is going to cover &lt;a href="http://codesushi.blogspot.com/2006/04/codesushi-goes-italian.html"&gt;specifically the italian scene&lt;/a&gt; and it is switching to italian.&lt;br&gt; &lt;br&gt; Using CodeSushi as a platform and meeting point I am going to push directly the italian software development scene&amp;nbsp; and see what comes up&amp;nbsp; from there.&amp;nbsp; &lt;br&gt; &lt;br&gt; The Liquid Development blog will continue as usual. &lt;br&gt; &lt;br&gt; And remember.. Code Sushi, not Spaghetti Code ;-)&lt;br&gt; &lt;br clear="all"&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114484166593058627?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114484166593058627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114484166593058627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114484166593058627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114484166593058627'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/codesushi-covering-italian-scene.html' title='CodeSushi: Covering the Italian Scene'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114478293387501329</id><published>2006-04-11T21:15:00.000+02:00</published><updated>2006-04-11T21:15:34.096+02:00</updated><title type='text'>Software Management as Development of a Business Abstraction</title><content type='html'>A very pretty &lt;a href="http://www.joelonsoftware.com/articles/DevelopmentAbstraction.html"&gt;piece from Joel &lt;/a&gt;- or how you know when management is failing badly.&lt;br&gt;&lt;br&gt;It is too often the case that developers -and employees in general- have to pay with extra working hours for management failures.. &lt;br clear="all"&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114478293387501329?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114478293387501329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114478293387501329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114478293387501329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114478293387501329'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/software-management-as-development-of.html' title='Software Management as Development of a Business Abstraction'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114466450795134802</id><published>2006-04-10T12:21:00.000+02:00</published><updated>2006-04-10T12:21:48.436+02:00</updated><title type='text'>Concrete Patterns Example</title><content type='html'>I dug out an old link to some &lt;a href="http://www2.ing.puc.cl/%7Ejnavon/IIC2142/patexamples.htm"&gt;concrete examples of Patterns&lt;/a&gt;.&lt;br&gt; Considering how hard it can be to explain some of the esoteric development stuff, this can be an inspiration for us all.&lt;br clear="all"&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114466450795134802?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114466450795134802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114466450795134802' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114466450795134802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114466450795134802'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/concrete-patterns-example.html' title='Concrete Patterns Example'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114445671516609003</id><published>2006-04-08T02:33:00.000+02:00</published><updated>2006-04-08T02:38:35.190+02:00</updated><title type='text'>The Book is Out (?!)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5227/1600/1600/liquid_development_for_dummies.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/5227/1600/320/liquid_development_for_dummies.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;What can I say?&lt;br /&gt;&lt;br /&gt;I think that &lt;a href="http://www.kumo.it/"&gt;Kumo &lt;/a&gt;has got far too much time on his hands!&lt;br /&gt;&lt;br /&gt;Thanks Kumo, much appreciated :-)&lt;br /&gt;&lt;br /&gt;Let's say it's a late April Fool..&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114445671516609003?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114445671516609003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114445671516609003' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114445671516609003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114445671516609003'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/book-is-out.html' title='The Book is Out (?!)'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114440975203154416</id><published>2006-04-07T13:35:00.000+02:00</published><updated>2006-04-07T13:35:52.233+02:00</updated><title type='text'>Upcoming Development Events in Italy</title><content type='html'>Italy has never been very active on the international development scene.&amp;nbsp; Let's see if we can turn this around :-)&lt;br&gt; &amp;nbsp;&lt;br&gt; Just a few links that make me proud:&lt;br&gt; &lt;ul&gt;   &lt;li&gt;&lt;a href="http://essap.dicom.uninsubria.it/"&gt;Summer School on Agility&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;&lt;a href="http://italyonrails.com/"&gt;Italy on Rails&lt;br&gt;     &lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114440975203154416?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114440975203154416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114440975203154416' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114440975203154416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114440975203154416'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/upcoming-development-events-in-italy.html' title='Upcoming Development Events in Italy'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114436484273192133</id><published>2006-04-07T01:07:00.000+02:00</published><updated>2006-04-07T01:07:22.736+02:00</updated><title type='text'>Style and Stanzas</title><content type='html'>The same piece of code can be written in a thousand ways, and every way has different tradeoffs in terms or readibility, expressiveness, debuggability, verbosity, etc..&lt;br&gt;&lt;br&gt;Jean-Charles Carelli recently asked on the rubytalk mailing list how to improve on the following style from the pickaxe book: &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;# 1 Book example &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;songs.append(Song.new(title, name, mins.to_i * 60 + secs.to_i))&lt;/span&gt;  &lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;  # 2 Alternate version.&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;duration = mins.to_i * 60 + secs.to_i&lt;/span&gt;  &lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;songs.append(Song.new(title, name, duration))&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;  I like a multi-line nested format, that I call  &lt;span style="font-style: italic; font-weight: bold;"&gt;Stanza &lt;/span&gt;- you know, like in &lt;a href="http://en.wikipedia.org/wiki/Stanza" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;poetry&lt;/a&gt;.&lt;br&gt;&lt;br&gt;  It looks like the following:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;  songs.append Song.new(&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; title,&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;name, &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;duration = ( mins.to_i * 60 + secs.to_i )&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt;&lt;br&gt;It clearly shows you what you are appending as a chunk of code on the right. the 'duration =' idiom makes the &lt;a href="http://liquiddevelopment.blogspot.com/2006/02/distilling-intent-from-descriptions_05.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;  intent&lt;/a&gt; explicit.&amp;nbsp;&amp;nbsp;I use brackets to nest conceptual entities (Song, duration), so that they stand out as visually striking, which is useful if you are doing some &lt;a href="http://liquiddevelopment.blogspot.com/2006/04/gestalt-code-reading.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;  Gestalt Code Reading&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Sometimes, using metaprogramming I also get rid of the explicit new by wrapping up object instantiation with a Song(..) method on the top level.&amp;nbsp;&amp;nbsp;I use this &lt;span style="font-weight: bold; font-style: italic;"&gt;Implicit Constructor&lt;/span&gt; because I don't want to be concerned with object creation in my code, just with the meaning of the entities that I am manipulating. &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;songs.append   Song(&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; title, &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;name,&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;duration = ( mins.to_i * 60 + secs.to_i )&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br clear="all"&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114436484273192133?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114436484273192133/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114436484273192133' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114436484273192133'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114436484273192133'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/style-and-stanzas_07.html' title='Style and Stanzas'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114422897384800039</id><published>2006-04-05T11:22:00.000+02:00</published><updated>2006-04-05T11:22:54.590+02:00</updated><title type='text'>Perceptual Stances: Start Small</title><content type='html'>I am interested in the tricks and hacks that we can use to somehow 'mechanically' steer and control our perception.&amp;nbsp;&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold;"&gt;Presentation Formats &lt;/span&gt;are one way to do this, forcing you to express some content within an artificially imposed presentation frame.&amp;nbsp;&amp;nbsp;The unusual 'shape' of the container can force you to reshape the content and discover some previously hidden properties.&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold;"&gt;Perceptual Stances&lt;/span&gt; (Thinking Formats?) do the same thing by forcing us to focus only on certain aspects of our subject matter.&amp;nbsp;&amp;nbsp;Business Pundit wrote an &lt;a href="http://www.businesspundit.com/50226711/how_to_find_topics_to_blog.php"&gt;interesting post&lt;/a&gt; that points out how you can unleash your creativity and get started by focusing on small thing rather than on grand theories and stereotypical thinking.&lt;br&gt;&lt;br&gt;It strikes me that some of the examples he uses seem almost related to techniques I found in &lt;a href="http://www.drawright.com/"&gt;Drawing On The Right Side of Your Brain&lt;/a&gt;: &lt;span style="font-weight: bold;"&gt; Drawing Negative Spaces&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;Semantic-Neutral Drawing&lt;/span&gt;.&amp;nbsp; These are not the names the author would have used, but if you are interested I can expand on them.&lt;br&gt; &lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114422897384800039?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114422897384800039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114422897384800039' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114422897384800039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114422897384800039'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/perceptual-stances-start-small.html' title='Perceptual Stances: Start Small'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114419775381990640</id><published>2006-04-05T02:42:00.000+02:00</published><updated>2006-04-05T02:42:33.916+02:00</updated><title type='text'>Presentation Formats: Lightning Talks</title><content type='html'>Lighnting talks are quick nuggets of information, usually delivered within 5 minutes.  I like formats, because they force you to take unusual approaches and points of view.  I like space and time constraints, because they force you to be synthetic and expressive.&lt;br /&gt;&lt;br /&gt;Have a look at the Lightning Talk format:&lt;br /&gt;* &lt;a href="http://www.perl.com/pub/a/2004/07/30/lightningtalk.html"&gt;Giving Lightning Talks&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://www.justanotherperlhacker.org/lightning/"&gt;Lightning Talks&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114419775381990640?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114419775381990640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114419775381990640' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114419775381990640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114419775381990640'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/presentation-formats-lightning-talks.html' title='Presentation Formats: Lightning Talks'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114410554254528171</id><published>2006-04-04T01:05:00.000+02:00</published><updated>2006-04-04T01:05:42.646+02:00</updated><title type='text'>Gestalt Code Reading</title><content type='html'>This is a follow up from some considerations in the comment section of the &lt;a href="http://liquiddevelopment.blogspot.com/2006/04/minimal-descriptions-and.html"&gt;previous post&lt;/a&gt;.&lt;br&gt;&lt;br&gt;If you have been writing code for some time I am sure that from time to time you also experience the weird psycognostic power of gestalt-reading code.&amp;nbsp; When I say gestalt-reading I mean that feeling of absorbing the main points and relationships of code by simply giving it a quick glance, just flicking through several pages of code.&amp;nbsp;  &lt;br&gt;&lt;br&gt;You don't know exactly what you have read, but you somehow have an overall impression of what the code does and how the different abstractions are related.&lt;br&gt;&lt;br&gt;What do you think this is due to?&amp;nbsp; &lt;br&gt;&lt;br&gt;I believe it is a mix of code indentation, code conventions, general domain culture and the ability of visualizing code on the fly via iconic images.&amp;nbsp; Next time you use your superpowers pay attention  to what is happening within your perception process.&amp;nbsp; If your perceptual habits are even a little bit similar to mine, you will probably notice that when you read code you see little boxes and arrows, popping into existence on the backstage of your counscius awareness, connecting together according to well-known patterns. &lt;br&gt;&lt;br&gt;The knowledge of this process may turn out to be quite important when deciding what code should look like.&amp;nbsp; Proper alignment of braces and indentations.. the feeling of un-closure that I sometimes feel when looking at python code (it feels more like a flow than like legos).&amp;nbsp; My mind looks for visual patterns and simplifies them into icons and boxes, probably also relying on subtler cues and unconscious processes to build meaning. &lt;br&gt;&lt;br&gt;It's interesting to see what information we can get from this kind of code reading.&amp;nbsp; I can get the main conceptual entities because I can visually spot classes and attributes.&amp;nbsp; I can get the broader relationships too, probably because of a good rational choice of class names, sometimes due to the naming of attributes, occasionally by seeing how some object instances are built and attached to each other.&amp;nbsp; I rarely get the algorithms at a first glance, although I seem to remember that I used to be able to, before doing OOP.. but I am not sure if that really was the case, in the same way as I can do it now with objects.&amp;nbsp; One thing is for sure: much of the metaprogramming cleverness is lost. &lt;br&gt;&lt;br&gt;However, if the metaprogramming could be kept simple and regular and visually striking, then it could be absorbed much more easily.&amp;nbsp; Think about ActiveRecord.&amp;nbsp; Maybe it doesn't matter so much how we say something, as long as we can make it visually recognisable and compelling, so that it promotes easy visual parsing. &lt;br&gt;&lt;br&gt;I was almost giving all sorts of non-visual code reading now, and I was forgetting test code.&amp;nbsp; Test code is a conspicuous exception to what I have just said about visual parsing.&amp;nbsp; If a project has tests I prefer to read the tests rather than the project code.&amp;nbsp; Tests are better at capturing the intent of the code and the way to interact with it.&amp;nbsp; They also clearly capture the dynamics of instances, providing not only a compositional/structural view of code, but also the modes of interaction with the code.&amp;nbsp; However tests must be read and cannot be simply absobed using gestalt-reading.&amp;nbsp; Maybe that's because they tend to specify behaviour rather than structure... &lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114410554254528171?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114410554254528171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114410554254528171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114410554254528171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114410554254528171'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/gestalt-code-reading.html' title='Gestalt Code Reading'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114402026886701973</id><published>2006-04-03T01:24:00.000+02:00</published><updated>2006-04-03T01:24:28.873+02:00</updated><title type='text'>Minimal Descriptions and Metaprogramming</title><content type='html'>My fellow &lt;a href="http://liquiddevelopment.blogspot.com/2006/03/ruby-social-club-1st-april-milan.html"&gt;socialite&lt;/a&gt; Pilu has opened a blog, &lt;a href="http://guragedev.blogspot.com/"&gt;Gurage&lt;/a&gt;,  where he provides an introductive examples to Rails.&amp;nbsp; He uses a simple inheritance example describing a Guitarist and a Singer as being two subclasses of Artist. &lt;br&gt;&lt;br&gt;While reading his code, that describes a Struct-like class (more an holder of attributes than an holder of behaviours) I thought back to a discussion that we had at the Ruby Social Club meeting about metaprogramming tricks.&amp;nbsp; My point was that through metaprogramming you can redefine the language in such a way that you can also provide stereotypical descriptions for classes and methods, so that you don't have to explicitly describe initializer, accessors, and so on. &lt;br&gt;&lt;br&gt;For example, this code written by Pilu&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; font-family: courier new,monospace; color: rgb(51, 51, 255);" class="gmail_quote"&gt; &lt;pre&gt;class Artist&lt;br&gt;  attr_reader :name&lt;br&gt;  def initialize(name)&lt;br&gt;    @name = name&lt;br&gt;  end&lt;br&gt;end&lt;/pre&gt;&lt;/blockquote&gt;could easily become something like:&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; color: rgb(51, 51, 255); font-weight: bold;" class="gmail_quote"&gt; &lt;pre&gt;Artist = Struct.new :name&lt;/pre&gt;&lt;/blockquote&gt; &lt;br&gt;This second form is no doubt more compact, but is it better?&lt;br&gt;&lt;br&gt;Forget the fact that the full class definition already provides the 'space' to add in new methods and attributes. Assume that the code is done and you are simply reading it.&amp;nbsp; What is better? and why? &lt;br&gt;&lt;br&gt;Something tells me that I would like the more terse and compact form, but somehow I still find that the first form has got something that the compact form lacks. I just can't put my finger on it.&lt;br&gt;&lt;br&gt;Following on from Pilu's example I would like to have a compact formalism that allows me to say something like: &lt;br&gt;&lt;br style="font-weight: bold;"&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 102, 0); font-weight: bold;"&gt; Artist defined by name&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 102, 0); font-weight: bold;"&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 102, 0); font-weight: bold;"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 102, 0); font-weight: bold;"&gt; Guitarist is an Artist also defined by guitar&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 102, 0); font-weight: bold;"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 102, 0); font-weight: bold;"&gt; Singer is an Artist also defined by microphone&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;Using metaprogramming is not too hard to generate this kind of Minimal Descriptions, although they would probably look like this:&lt;br&gt;&lt;br style="color: rgb(51, 51, 255); font-weight: bold;"&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; color: rgb(51, 51, 255); font-weight: bold;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace;"&gt; Artist = defined_by :name&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;   &lt;br style="font-family: courier new,monospace;"&gt;   &lt;span style="font-family: courier new,monospace;"&gt;Guitarist = Artist.also_defined_by :guitar&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;   &lt;span style="font-family: courier new,monospace;"&gt;Singer = Artist.also_defined_by :microphone&lt;/span&gt;&lt;/blockquote&gt;&amp;nbsp;&lt;br&gt;I will leave the metaprogramming as an exercise for the reader :-D&lt;br&gt;&lt;br&gt;The 'defined_by' is just wrapping a call to ' Struct.new', probably also adding a few extras such as a comparison operator and a prettier to_s method.&amp;nbsp; The 'also_defined_by' is a method that has been injected into the Class class.&amp;nbsp; It creates a new anonymous subclass, adding a few extra accessors and also overriding the initializer by adding some extra parameters. &lt;br&gt;&lt;br&gt;We have seen how this is technically feasible, I just wonder if this is what we want.&amp;nbsp; &lt;br&gt;&lt;br&gt;The standard way of doing things shows us explicitly that we are dealing with a class.&amp;nbsp; The 'class' and the 'end' words and the indentation highlight clearly a&amp;nbsp; chunk of code and identifies it as being a class, an important&amp;nbsp; concept within the narrative of our system. &lt;br&gt;&lt;br&gt;The Minimal Description approach tries to hide away the whole concept of class.&amp;nbsp; It simply cares about concepts and meaning and it abstracts away a big body of knowledge.&amp;nbsp; The body of knowledge that is abstracted away&amp;nbsp; is that we are defining classes and that these classes are related by inheritance.&amp;nbsp; It is also assuming that we know that if something is defined by a certain characteristic, then this characteristic will have to be used when creating an instance of that concept. &lt;br&gt;&lt;br&gt;What do you think?&amp;nbsp; Is this a rightful use of metaprogramming and of Shaping code After Language, or is it a blatant abuse of metaprogramming power?&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114402026886701973?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114402026886701973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114402026886701973' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114402026886701973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114402026886701973'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/04/minimal-descriptions-and.html' title='Minimal Descriptions and Metaprogramming'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114366910985252388</id><published>2006-03-29T23:51:00.000+02:00</published><updated>2006-03-29T23:51:49.876+02:00</updated><title type='text'>Apology of Excel and Excelagility Part III - Streaming Objects from/to Excel</title><content type='html'>&lt;div&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 18pt; COLOR: #3366ff; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt; &lt;div&gt; &lt;div&gt;&lt;font face="courier new,monospace" color="#000000" size="2"&gt;I hope that some of you are actually reading these posts on Excel.&lt;/font&gt;&lt;/div&gt; &lt;div&gt;&lt;font face="courier new,monospace" color="#000000" size="2"&gt;I know, it's not a very sexy topic, but I would like to convince you&amp;nbsp;that &lt;strong&gt;in some contexts&lt;/strong&gt;, under&amp;nbsp;&lt;strong&gt;specific conditions&lt;/strong&gt;, it can be a real kick-ass environment for truly agile development. &lt;/font&gt;&lt;/div&gt; &lt;div&gt;&lt;font face="courier new,monospace" color="#000000" size="2"&gt;&lt;/font&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;font face="courier new,monospace" color="#000000" size="2"&gt;I agree, VBA is now pretty old and it has several limitations.. but less than you would normally think.&amp;nbsp; In the course of the future posts you might find a few interesting and generally useful tricks as I show you how to get around the lack of implementation inheritance and even do some degree of reflection and functional-style programming. &lt;/font&gt;&lt;/div&gt; &lt;div&gt;&lt;font face="courier new,monospace" color="#000000" size="2"&gt;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;font color="#000000" size="2"&gt;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;/span&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 18pt; COLOR: #3366ff; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt; Excelagility &lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 18pt; COLOR: #3366ff; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt; - or -&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 18pt; COLOR: #3366ff; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt; How to Shape Excel with VBA into a Legible Expressive Agile Platform&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;span style="FONT-FAMILY: 'Courier New'"&gt;~&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;V. 0.0.4&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;div&gt;&amp;nbsp;&lt;/div&gt; &lt;div&gt;&lt;br&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span lang="EN-GB" style="COLOR: #3366ff; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt; Writing Objects to Excel&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;We have seen how to write out objects to the Immediate Window, but what about writing them to the Excel sheets? &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;After all we set out to work and to be productive within the Excel environment, didn't we?&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;All you need to do is to extend your class with a 'toExcel' method. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #3366ff 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: #3366ff 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #3366ff 1pt solid; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #3366ff 1pt solid; mso-border-alt: solid #3366FF .5pt"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Sub toExcel(startcell As Range) &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;startcell.Offset(0,0) = Me.Name&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;startcell.Offset(0,1) = Me.Surname&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;startcell.Offset(0,2) = Me.DateOfBirth&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;End Sub&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;That's it!&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #3366ff 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: #3366ff 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #3366ff 1pt solid; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #3366ff 1pt solid; mso-border-alt: solid #3366FF .5pt"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Dim a_person As Person&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Set a_person = Person("John","Smith",#23/11/1980#)&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;a_person.toExcel [B3]&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;a_person.toExcel Workbooks("Book1.xls"). _ &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Worksheets("Sheet2"). _&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Range("D10")&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;a_person.toExcel Workbooks("Book1.xls"). _ &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Worksheets("Sheet2"). _&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Range("my named cell")&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;This code will allow you to write out your person to Excel, horizontally. &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;If you want to write it vertically, then you would have had to swap the row and column numbers in the call to the 'Offset' function within the 'toExcel' method.&lt;span style="mso-spacerun: yes"&gt; &amp;nbsp; &lt;/span&gt;You could parametrize the method with an optional parameter to choose the direction of the print out.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span lang="EN-GB" style="COLOR: #3366ff; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt; Reading&lt;/span&gt;&lt;/b&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span lang="EN-GB" style="COLOR: #3366ff; FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt; Objects from Excel&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Now that we are able to write out Person objects to excel we would also like to allow our users to edit the excel sheet before loading this data back into VBA. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;We have seen how to build a Person programmatically, using a  &lt;b style="mso-bidi-font-weight: normal"&gt;Noun&lt;/b&gt; function.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;We will now see how to assemble a Person object from data found on an Excel sheet.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;First of all we need a way to create a new Person from scratch, without setting any of its attributes. &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Once we have a Person object we can then call a 'fromExcel' method to initialise its attributes.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;This could be written as:&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #3366ff 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: #3366ff 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #3366ff 1pt solid; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #3366ff 1pt solid; mso-border-alt: solid #3366FF .5pt"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Dim a_person As Person&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Set a_person = New Person&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;a_person.fromExcel [b4]&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;However, as we are quite lazy, we would prefer to write something like: &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #3366ff 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: #3366ff 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #3366ff 1pt solid; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #3366ff 1pt solid; mso-border-alt: solid #3366FF .5pt"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Dim a_person As Person&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Set a_person = Person_fromExcel [b4]&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;The command 'Person_fromExcel' can be defined as a new Noun that assembles new Person objects from a cell reference. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #3366ff 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: #3366ff 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #3366ff 1pt solid; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #3366ff 1pt solid; mso-border-alt: solid #3366FF .5pt"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Module Nouns&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Function Person_fromExcel( _&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;startcell As Range _&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;) As Person&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 72pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Set Person = New Person&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 72pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Person.fromExcel startcell&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;End Function&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;End Module&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;All that is left to do is to define the 'fromExcel' method. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #3366ff 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: #3366ff 1pt solid; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #3366ff 1pt solid; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #3366ff 1pt solid; mso-border-alt: solid #3366FF .5pt"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Sub fromExcel(startcell As Range) &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Me.Name = startcell.Offset(0,0) &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Me.Surname = startcell.Offset(0,1)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; TEXT-INDENT: 36pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Me.DateOfBirth = startcell.Offset(0,2)&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: solid #3366FF .5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;End Sub&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Unsurprisingly, we can see that it is the almost exact converse of the 'toExcel' method. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;Being able to read and write objects from and to excel is invaluable when you are trying to reason on the objects of your problem and you want to be able to edit them while the program is running. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB; mso-fareast-font-family: Batang"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114366910985252388?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114366910985252388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114366910985252388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114366910985252388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114366910985252388'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/apology-of-excel-and-excelagility-part.html' title='Apology of Excel and Excelagility Part III - Streaming Objects from/to Excel'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114350189455270811</id><published>2006-03-28T01:14:00.000+02:00</published><updated>2006-03-28T01:24:54.553+02:00</updated><title type='text'>Ruby Social Club - 1st April Milan Meeting</title><content type='html'>The Ruby Social Club is getting up to speed and spreading fast.  After the first two meetings in Rome we are going to meet up in Milan on the evening of saturday the first of April.&lt;br /&gt;&lt;br /&gt;In the course of the first two meetings I have met very nice easy going people, and very competent brilliant developers too.  It's hard to find the right alchemy that allows you to talk offhandedly with newly met people about metaprogramming and semiotics, while drinking good wine and picking at &lt;a style="font-style: italic;" href="http://it.wikipedia.org/wiki/Immagine:Arrosticini_01.jpg"&gt;arrosticinos&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The avenue has not been defined yet, but you can keep up to date via our italian &lt;a href="http://ruby-it.org/pages/Ruby+Social+Club"&gt;Ruby-It wiki page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you fancy catching up with us there, get in touch with us and we will make sure there is enough wine and food for you too :-)&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114350189455270811?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114350189455270811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114350189455270811' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350189455270811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350189455270811'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/ruby-social-club-1st-april-milan.html' title='Ruby Social Club - 1st April Milan Meeting'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114350124243385761</id><published>2006-03-28T01:09:00.000+02:00</published><updated>2006-03-28T01:14:02.433+02:00</updated><title type='text'>The Art of Shaping</title><content type='html'>Shaping Code After Language is in the air.. and I believe it is the way to go.  In these two posts I am trying to capture the spirit of &lt;span style="font-style: italic;"&gt;Shal&lt;/span&gt; and put it down on paper..&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2005/11/shape-code-after-language.html"&gt;Shaping Code After Language I&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2005/11/shape-code-after-language-ii.html"&gt;Shaping Code After Language II&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114350124243385761?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114350124243385761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114350124243385761' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350124243385761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350124243385761'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/art-of-shaping.html' title='The Art of Shaping'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114350096102288785</id><published>2006-03-28T01:08:00.000+02:00</published><updated>2006-06-08T11:16:59.543+02:00</updated><title type='text'>The Way of Meta</title><content type='html'>The first four and half installments of an exploration of Ruby Metaprogramming&lt;br /&gt;&lt;br /&gt;&lt;ul id="recently"&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-i.html"&gt;The Way of Meta - Part I&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-ii.html"&gt;The Way of Meta - Part II&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-iii.html"&gt;The Way of Meta - Part III&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/04/way-of-meta-part-iv-hijacking-local.html"&gt;The Way of Meta - Part IV&lt;/a&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/04/twisting-and-shaping-dsls-using-ruby.html#links"&gt;Part IV and half :-)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114350096102288785?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114350096102288785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114350096102288785' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350096102288785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350096102288785'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/way-of-meta.html' title='The Way of Meta'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114350089601080764</id><published>2006-03-28T01:06:00.000+02:00</published><updated>2006-03-28T01:08:16.013+02:00</updated><title type='text'>Evolving Intent</title><content type='html'>My explorations of Intent and how it develops from Test Driven Design&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2005/11/instant-intent.html"&gt;Instant Intent&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-proze_12.html"&gt;Intent and Proze I&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-03.html"&gt;Intent and Proze II&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-04-intents-stories-and-facts.html"&gt;Intents, Stories and Facts&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2005/12/tests-as-storytelling.html"&gt;Storytelling&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://codesushi.blogspot.com/2005/11/maru-batsu.html"&gt;Evolving Maru Batsu from Intents I&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://codesushi.blogspot.com/2005/12/maru-batsu-ii.html"&gt;Evolving Maru Batsu from Intents II&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/02/distilling-intent-from-descriptions_05.html"&gt;Distilling Intent From Descriptions&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114350089601080764?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114350089601080764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114350089601080764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350089601080764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350089601080764'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/evolving-intent.html' title='Evolving Intent'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114350074453710212</id><published>2006-03-28T01:02:00.000+02:00</published><updated>2006-03-28T01:05:44.553+02:00</updated><title type='text'>Excelagility - Shaping VBA into an Agile Platform</title><content type='html'>The first two draft installments of my attempt at showing the power of Shaping Code After Language and redeeming Excel and VBA as an agile platform..&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/03/excelagility-part-i.html"&gt;Excelagility - Part I&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/03/excelagility-part-ii-printing-out.html"&gt;Excelagility - Part II - Printing out objects with external polymorphism&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114350074453710212?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114350074453710212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114350074453710212' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350074453710212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114350074453710212'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/excelagility-shaping-vba-into-agile.html' title='Excelagility - Shaping VBA into an Agile Platform'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114185292460480565</id><published>2006-03-08T22:22:00.000+01:00</published><updated>2006-03-08T22:22:04.613+01:00</updated><title type='text'>Updated Table of Content</title><content type='html'>I have updated the &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/liquid-development-toc.html"&gt;Liquid Development Table of Contents&lt;/a&gt; with the latest posts..&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114185292460480565?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114185292460480565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114185292460480565' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114185292460480565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114185292460480565'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/updated-table-of-content.html' title='Updated Table of Content'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114184554944823483</id><published>2006-03-08T20:19:00.000+01:00</published><updated>2006-03-08T20:19:09.476+01:00</updated><title type='text'>Excelagility - Part II - Printing out objects with external polymorphism</title><content type='html'>  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: left; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;font size="2"&gt; Where we explore how to get rid of some of the verbose bureaucracy of VBA and how to create uniformity using 'Verbs' and external polymorphism..&lt;br&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: left; color: rgb(0, 0, 0);"&gt; &lt;b style=""&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family: arial,sans-serif;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;font size="2"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;b style=""&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt; &lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;&lt;/span&gt;Excelagility &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;b style=""&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;- or -&lt;span style=""&gt; &amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;b style=""&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;How to Shape Excel with VBA into a Legible Expressive Agile Platform&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;"&gt;~&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;V. 0.0.2&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;Printing Out Objects&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Now we have objects, but it's not easy to print them out to screen, for example for debugging purposes.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;We can do this by providing each class which is of interest to us with a method that converts it to string: a 'toString' method.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Dim a_person As Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Set a_person = Person("John","Smith",#23/11/1980#) &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Debug.Print a_person.toString&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Let's add such a method to the 'Person' class:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Function toString() As String&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;toString = "Person(" &amp;amp; _&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;Me.Name &amp;amp; ", " &amp;amp; _&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;Me.Surname &amp;amp; ", " &amp;amp; _&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;Me.DateOfBirth &amp;amp; ") " &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End Function&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Now you can easily print out a Person object to the Immediate Window.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;However, having to write 'Debug.Print' and 'toString' is quite verbose and we can devise a way to make this more readable.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Sub puts(an_entity) &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Debug.Print strize(an_entity)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End Sub&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;The new 'puts' command substitutes the lengthy 'Debug.Print' command and it also forces the argument passed to it to be converted to a string.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;The actual conversion is performed by the 'strize' (short for string-ize) function.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;The code for the 'strize' function employs a technique that I call 'external polymorphism' to handle entities of any type and not only Objects.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Function strize(an_entity) As String&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;If IsObject(an_entity) Then&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strize = an_entity.toString &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Else&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strize = CStr(an_entity) &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End If&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End Function&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;This code now allows you to write much more expressive statements:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Dim a_person As Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Set a_person = Person("John","Smith",#23/11/1980#) &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;puts a_person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;puts a_person.DateOfBirth&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;puts a_person.Name&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;The 'puts' command, however, is not as robust as we would like it to be.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;If you pass it an object that does not implement the 'toString' method, then it will fail without providing much of an explanation.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;We can make it more robust by adding some simple error handling:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Function strize(an_entity) As String&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;On Error Goto cannot_convert_to_string&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;If IsObject(an_entity) Then &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strize = an_entity.toString&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Else &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style=""&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strize = CStr(an_entity)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;End If &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Exit Function&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;cannot_convert_to_string:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;strize = TypeName(an_entity)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End Function&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;If the entity passed cannot be converted to string, then we recover by returning simply the type name of the entity.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Alternatively we may want it to return an error message, using the 'MsgBox' command.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;  &lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114184554944823483?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114184554944823483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114184554944823483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114184554944823483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114184554944823483'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/excelagility-part-ii-printing-out.html' title='Excelagility - Part II - Printing out objects with external polymorphism'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114168866024742230</id><published>2006-03-07T00:44:00.000+01:00</published><updated>2006-03-07T00:44:25.843+01:00</updated><title type='text'>Excelagility - Part I</title><content type='html'>This is the first installment o a serie on how to shape VBA and Excel into a useful agile tool.&amp;nbsp;&amp;nbsp;I know, it's difficult to believe, but it can be done! &lt;br&gt;&lt;br&gt;How can I convince you of the usefulness of this well known unholy duo? :-) &lt;br&gt;&lt;br&gt;For the time being, let it suffice to say that one of the main tenets of liquid development is not just to work with users, but to get users to write code with us.. and one of the best way to get them to write code, to directly express their intent, is to do it in such a way that they don't even realize they are coding. &lt;br&gt;&lt;br&gt;In the course of these installments I will try to prove this point and to show you at the same time how you can Shape Language to your needs, even if it is VBA.&lt;br&gt;&lt;br&gt;&lt;br&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;b style=""&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;Excelagility &lt;/span&gt; &lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;b style=""&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;- or -&lt;span style=""&gt; &amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;b style=""&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;How to Shape Excel with VBA into a Legible Expressive Agile Platform&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;"&gt;~&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 10pt; font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;V. 0.0.2&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;Introduction&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;This booklet will show you how to be agile and effective using Excel with VBA.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;Defining Classes&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;When you design a class for an excel addin, keep the class private, unless you need to use it from another module (more on this later).&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Class Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Public Name As String&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Public Surname As String&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Public DateOfBirth As Date&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End Class&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Use public properties, as in:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Public Name as String&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Public properties make the code much simpler to read and can always be privatised later, should the need arise.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style="" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;Assembling Objects with Nouns&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Once a class has been defined, objects are easy to create:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Dim a_person As Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Set a_person = New Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_person.Name = "John"&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_person.Surname = "Smith"&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_person.DateOfBirth = #11/23/1980#&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Although objects in VBA can be created with a simple 'New' statement, we prefer to use a somewhat more articulate method.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Since we want to have exact control on how an object gets created, initialised and built, we introduce an intermediate layer that takes care of assembling objects for us.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;This layer should allow you to create and initialise objects in a much more readable way:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Dim a_person As Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Set a_person = Person("John","Smith",#11/23/1980#) &lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;We name this layer the Nouns layer, and we represent it as a Nouns module present in every excel add-in.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1pt solid rgb(51, 102, 255); padding: 1pt 4pt; margin-left: 36pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Module Nouns&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Function Person( _&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_name As String, _&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_surname As String, _&lt;/span&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_date_of_birth As Date _&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;) As Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Dim a_new_person As Person &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Set a_new_person = New Person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_new_person.Name = a_name&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_new_person.Surname = a_surname&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;a_new_person.DateOfBirth = a_date_of_birth&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 72pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;Set Person = a_new_person&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify; text-indent: 36pt;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End Function&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;End Module&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;;" lang="EN-GB"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;    &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114168866024742230?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114168866024742230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114168866024742230' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114168866024742230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114168866024742230'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/03/excelagility-part-i.html' title='Excelagility - Part I'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114056175685558777</id><published>2006-02-21T23:42:00.000+01:00</published><updated>2006-02-21T23:42:37.190+01:00</updated><title type='text'>The Way of Meta - Part III</title><content type='html'>&lt;div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 18pt; FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;The Way of &lt;/span&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 18pt; FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt; Meta&lt;/span&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 18pt; FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;~&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;V. 0.0.3&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: center" align="center"&gt;&lt;span lang="EN-GB" style="FONT-SIZE: 10pt; FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt; &lt;div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span lang="EN-GB" style="COLOR: green; FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;Writing Method Generators &lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;I am going to write a simple example that illustrates how you can create a method generator: a construct used within a class definition as a shortcut to generate richer method semantics, in the same way that attr_accessor generates enrich class behaviour by adding new methods.  &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;This example concerns the development of a 'synonym' generator.&lt;span style="mso-spacerun: yes"&gt; &amp;nbsp; &lt;/span&gt;A synonym is similar to an alias because it provides different calls to achieve the same result.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;It is different from an alias in that an alias generates a copy of a method, rather than a different name to call the same method. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;If an aliased method gets overridden, its aliases will keep calling the old code. &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Conversely, a synonym of a method is a simple light code layer that keeps calling a certain method name.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;If the aliased method gets overwritten, then all its synonyms will start calling the new version of the method. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;Let's start from our intent; let's visualise how we would like to use synonyms. &lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 45pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;class&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; Person&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;say&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;hi&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;walk&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;one step&amp;quot;&lt;/span&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;synonym&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;span style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:say&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt; &amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;=&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; [&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:talk&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:discuss&lt;/span&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :greet&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;],&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-tab-count: 2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :walk&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;=&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :stride&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :run&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :jump&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; mso-layout-grid-align: none"&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Lucida Sans Unicode'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;Here we are declaring that both the method 'say' and the method 'walk' have several synonyms. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;We also expect the following statements to be true&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p1&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; =&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;Person&lt;b&gt;.&lt;/b&gt;new&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;talk&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;== &lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;hi&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;discuss&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;== &lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;hi&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;greet&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;== &lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;hi&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;stride&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;==&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;one step&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;run&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;==&lt;/span&gt; &lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;one step&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;jump&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;==&lt;/span&gt; &lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;one step&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;They should become false when we override the old methods:&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;class&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; Person&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;say&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;yo&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;say&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;== &lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;yo&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;talk&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;== &lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;yo&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;discuss&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;== &lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;yo&amp;quot;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; p1&lt;b&gt;.&lt;/b&gt;greet&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;== &lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #7f007f; FONT-FAMILY: 'Courier New'"&gt;&amp;quot;yo&amp;quot;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;Enough talking, we have all the intent we need for a first stab at the problem.&lt;span style="mso-spacerun: yes"&gt; &amp;nbsp; &lt;/span&gt;Let's dive straight into the code.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;First of all we need a convenient way to process the arguments passed to the 'synonym' generator.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;Consider how we will need to elaborate the following hash:&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 45pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:say&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;=&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :talk&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :discuss&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :greet&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;],&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:walk&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;=&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; [&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:stride&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:run&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:jump&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;This is just a convenient idiom that we use to express the following relationships:&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 45pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; TEXT-INDENT: 27pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :say&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :talk&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;],&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; TEXT-INDENT: 27pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :say&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :discuss&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;],&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; TEXT-INDENT: 27pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :say&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :greet&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;],&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; TEXT-INDENT: 27pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :walk&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :stride &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ],&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; TEXT-INDENT: 27pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :walk&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :run&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;],&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; TEXT-INDENT: 27pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :walk&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :jump&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; TEXT-INDENT: 27pt; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;]&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;Let's write some code that can take us from the first compact format to the second explicit representation. &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;We will call the relationships 'associations' and we will provide a method that allows us to iterate over a hash one association at a time.&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;i&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #007f00; FONT-FAMILY: Arial"&gt;# expands a =&amp;gt; [b1,b2,b3] associations to [a,b1], [a,b2], [a,b3], etc.. &lt;/span&gt;&lt;/i&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;/span&gt; &lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;class&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: Arial"&gt; Hash&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: Arial"&gt;each_association&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt; &amp;amp;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;block&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;self&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt; .&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;each_pair&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt; do&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;|&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt; assoc_key&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;assoc_targets&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;assoc_targets&lt;b&gt;.&lt;/b&gt;to_a&lt;b&gt;.&lt;/b&gt;each &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;do&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;|&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;assoc_target&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;block&lt;b&gt;.&lt;/b&gt;call&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;assoc_key&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt; assoc_target&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;Now that we have a way to visit our associations, we will generate a new synonym method for each association: &lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;class&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; Module&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #007f00; FONT-FAMILY: 'Courier New'"&gt;# associations: ( old_name =&amp;gt; [new names] )* &lt;/span&gt;&lt;/i&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;synonym&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; associations&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;associations&lt;b&gt;.&lt;/b&gt;each_association &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;do&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;|&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; original_name_sym&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;new_name_sym&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;define_method&lt;b&gt;(&lt;/b&gt; new_name_sym&lt;b&gt;){&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;|*&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; args&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;self&lt;/span&gt; &lt;/b&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;.&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;send&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;original_name_sym&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; *&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;args&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;}&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span style="FONT-FAMILY: 'Comic Sans MS'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;For each association specified in the synonym generator we inject a new method in our class. &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;The new method has the name specified on the right hand side of the association, and all it does is to invoke the original method of the class.&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;The synonym generator has been defined within the Module class, so that it becomes automatically available within the context of the classes 'Module' and 'Class'. &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;We can now use the generator even to expand existing classes with new developer friendly names. &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;Here we tweak the Array class:&lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;Array&lt;b&gt;.&lt;/b&gt;class_eval&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt; do&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;synonym&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:size&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; =&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;[&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:count&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:n_elements&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ]&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; [&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;1&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 2&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;3&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ].&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;count&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;==&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 3&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 6pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; TEXT-ALIGN: justify; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; [&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;1&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 2&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;3&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ].&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;n_elements&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;==&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 3&lt;/span&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Courier New'; mso-ansi-language: EN-GB"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;And here we provide a way to talk to a Person, rather than giving him orders! &lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;class&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; Person&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;def&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;calculate&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;(&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; a&lt;b&gt;,&lt;/b&gt;op&lt;b&gt;,&lt;/b&gt;b&lt;b&gt;)&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;a&lt;b&gt;.&lt;/b&gt;send&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;op&lt;b&gt;,&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; b&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; (&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p1&lt;b&gt;.&lt;/b&gt;calculate&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 3&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :+&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 2&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;)&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ==&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;5&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;class&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt; Person&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;synonym&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:calculate&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; =&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:how_much&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ?&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: 'Courier New'"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; (&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;p1&lt;b&gt;.&lt;/b&gt;how_much?&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 3&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt; :+&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt; 2&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;)&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ==&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #007f7f; FONT-FAMILY: 'Courier New'"&gt;5&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;It is worth pointing out a small syntactic trick that we used to handle both cases of single ( &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:calculate&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; =&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:how_much&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ?&lt;/span&gt;&lt;/b&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;) and multiple synonyms (&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:size&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;=&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; [&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:count&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt; ,&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt; &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #c0a030; FONT-FAMILY: 'Courier New'"&gt;:n_elements&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: 'Courier New'"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'"&gt;]&lt;/span&gt;&lt;/b&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;).&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;We get the right hand side of the hash element and we apply 'to_a' to it, turning it into an array. &lt;/span&gt;&lt;/p&gt; &lt;div style="BORDER-RIGHT: #339966 1.5pt double; PADDING-RIGHT: 4pt; BORDER-TOP: #339966 1.5pt double; PADDING-LEFT: 4pt; PADDING-BOTTOM: 1pt; MARGIN-LEFT: 36pt; BORDER-LEFT: #339966 1.5pt double; MARGIN-RIGHT: 0cm; PADDING-TOP: 1pt; BORDER-BOTTOM: #339966 1.5pt double"&gt;  &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;i&gt;&lt;span style="FONT-SIZE: 9pt; COLOR: #007f00; FONT-FAMILY: Arial"&gt;…&lt;/span&gt;&lt;/i&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;assoc_targets&lt;b&gt;.&lt;/b&gt;to_a&lt;b&gt;.&lt;/b&gt;each &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;do&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;  &lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;|&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial"&gt;assoc_target&lt;b&gt;|&lt;/b&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;…&lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: #00007f; FONT-FAMILY: Arial"&gt;end&lt;/span&gt;&lt;/b&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt; &lt;/span&gt;&lt;/p&gt; &lt;p class="MsoNormal" style="BORDER-RIGHT: medium none; PADDING-RIGHT: 0cm; BORDER-TOP: medium none; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; MARGIN: 0cm 0cm 0pt; BORDER-LEFT: medium none; PADDING-TOP: 0cm; BORDER-BOTTOM: medium none; mso-layout-grid-align: none; mso-border-alt: double #339966 1.5pt; mso-padding-alt: 1.0pt 4.0pt 1.0pt 4.0pt"&gt; &lt;span style="FONT-SIZE: 10pt; COLOR: gray; FONT-FAMILY: Arial"&gt;…&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;&lt;/span&gt;&amp;nbsp;&lt;/p&gt; &lt;p class="MsoNormal" style="MARGIN: 0cm 0cm 6pt; TEXT-ALIGN: justify"&gt;&lt;span lang="EN-GB" style="FONT-FAMILY: 'Comic Sans MS'; mso-ansi-language: EN-GB"&gt;If the element is not an array, it gets turned into one.&lt;span style="mso-spacerun: yes"&gt; &amp;nbsp; &lt;/span&gt;If it is already an array, it is left unchanged.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;Whatever the case, we are left with a simple array to operate on in the end.&lt;/span&gt;&lt;/p&gt;&lt;br&gt;&amp;nbsp;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114056175685558777?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114056175685558777/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114056175685558777' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114056175685558777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114056175685558777'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-iii.html' title='The Way of Meta - Part III'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114037788746970962</id><published>2006-02-19T20:38:00.000+01:00</published><updated>2006-02-19T20:38:07.476+01:00</updated><title type='text'>The Way of Meta - Part II</title><content type='html'>  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;The Way of &lt;/span&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt; Meta&lt;/span&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 10pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt; V. 0.0.2&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-size: 14pt; font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Exploring Ruby Metaprogramming Capabilities&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Getting our Feet Wet&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;Tired of all this talk?&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Then it is time to dip our feet in the deep waters of rubesque metaprogramming.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;We are going to start our journey exploring the metaprogramming features that are illustrated in the pragmatic programmers' PickAxe book, while at the same time we will go through the less known libraries present in the ruby distribution.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;At the same time we will ask for some help to the wonderfully brief and clear 'Seeing Metaclasses Clearly' by Why the Lucky Stiff.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Out-of-the-Box Metaprogramming Mechanisms&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;Ruby provides several straight out of the box metaprogramming mechanisms with its core standard libraries.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Although using these mechanisms can take you very quickly to unmanageable levels of complexity it is worth looking at them to have a feeling of what is possible.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Later on we will encapsulate these mechanisms within our own metaprogramming protocol.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;br&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Loading Code&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt; &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;In many languages, the mechanism that allows your source code to refer to a library or to another piece of code is handled by the language in an opaque way.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Not so in Ruby. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;When using Ruby you are in charge of the code loading.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;The 'load' command loads some ruby code, right where you are calling it.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1.5pt double rgb(51, 153, 102); padding: 1pt 4pt; background: white none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-left: 36pt; margin-right: 36pt;"&gt;   &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; background: white none repeat scroll 0%; margin-bottom: 6pt; text-align: justify; text-indent: 36pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;load &amp;quot;myfile.rb&amp;quot;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;The 'require' command adds a little check that prevents the loading of the same file twice from different points in the code.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1.5pt double rgb(51, 153, 102); padding: 1pt 4pt; background: white none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-left: 36pt; margin-right: 36pt;"&gt;   &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; background: white none repeat scroll 0%; margin-bottom: 6pt; text-align: justify; text-indent: 36pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt; &lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;require &amp;quot;filename&amp;quot;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;Load and require are not special commands for the compiler, they are dynamically executed and can be embedded within blocks, control statements, etc. &lt;span style=""&gt;&amp;nbsp;&lt;/span&gt;The name of the file that they load can also be constructed dynamically.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;The load construct in particular allows you to reload code definitions any number of times if they get changed inside the file.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;It's now easy to see how your code could generate code files, maybe using a templating mechanism, and then load them back in the runtime.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1.5pt double rgb(153, 153, 153); padding: 1pt 4pt; margin-left: 27pt; margin-right: 0cm;"&gt;  &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: red;" lang="EN-GB"&gt;Principles of Ruby Metaprogramming I:  &lt;/span&gt;&lt;/b&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: red;" lang="EN-GB"&gt;Source&lt;b style=""&gt; &lt;/b&gt;Code Files are Dynamically Loaded, not Statically Included&lt;b style=""&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;There are two environment variables that can turn out to be helpful when dealing with dynamic source code loading.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;$LOAD_PATH is an array of directories that are searched for source code by 'load' and 'require'.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;$LOADED_FEATURES is an array containing the filenames of the files that have already been loaded.&lt;/span&gt;&lt;/p&gt;  &lt;br clear="all"&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114037788746970962?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114037788746970962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114037788746970962' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114037788746970962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114037788746970962'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-ii.html' title='The Way of Meta - Part II'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-114030982367548681</id><published>2006-02-19T01:43:00.000+01:00</published><updated>2006-02-19T01:43:43.926+01:00</updated><title type='text'>The Way of Meta - Part I</title><content type='html'>I might have mentioned it, but I am planning to write a book on Liquid Development.&amp;nbsp; A big part of Liquid Development is about shaping code and knowledge after our own linguistic structures.&amp;nbsp; Metaprogramming becomes a technique instrumental to shape and bend a language to your wishes. &lt;br&gt;&lt;br&gt;Today I am going to post the first part of a rough draft on metaprogramming that I am putting together for the book.&lt;br&gt;&lt;br&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;The Way of &lt;/span&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt; Meta&lt;/span&gt;&lt;span style="font-size: 18pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: center;" align="center"&gt;&lt;span style="font-size: 10pt; font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;V. 0.0.1&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Exploring Metaprogramming in Ruby&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;I have been a fan of metaprogramming techniques for a long time, but I have been able to fully indulge into this deplorable habit only after having taken up programming in Ruby.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;What's the deal with this metaprogramming thing?&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;There are lots of tutorials and introduction out there on the web, so I am not going to go into the historical details here, but I will give you my own personal definition of metaprogramming.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;br&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Metaprogramming as Deep Magick&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;Metaprogramming has meant different things at different times, but at any particular time what metaprogramming seems to mean, is the ability of somehow getting into the inner working of the language that you are using, so that you can produce what is sometimes referred to as "deep magick".&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;It does look and feel like magick, because when you go 'meta' with programming, you are moving outside the realm of everyday modelling, to step into the world that defines the very rules of ordinary programming.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;Many of the concepts of object orientation feel like metaprogramming the first time you see them.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;I clearly remember the sharp feeling of power and magick the first time I saw C++ operator overloading in action as a young man.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;It felt like I could plunge into the core of the language, inside the very definition of the metaphysics of programming and change the way I could represent the world, on a whole new level.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Metaprogramming considered Harmful&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;The term metaprogramming covers lots of ground, and it represents more a philosophical focus than a specific set of techniques.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;The capabilities of Metaprogramming can be potentially so powerful and far reaching that can also be completely devastating. &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;If you are able to tweak the underlying layer on top of which you build your representations, you can change the semantics of all the relationships that you have built between your 'ordinary' conceptual objects.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;This can add new features (aspects) to your program, or it can simply make it wrong, breaking its intent, or it can make it totally unworkable and inconsistent.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;It could also cause unforeseen interferences between your meta-code and the program, between two different sets of code, or within the libraries your code relies on.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Metaprogramming on the Leash&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;So, is Metaprogramming a good or a bad thing?&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;I would say that it is good if used parsimoniously, when no other conventional technique can yield the same elegance and results.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;It should also be used when it can help removing duplication in your code, while adding clarity to it.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;However it should be used in a very controlled way.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Metaprogramming almost always involve some degree of run-time creation and customisation of code that gets injected into the realtime machinery of your program.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;The code generated by your 'meta-code' is usually invisible to the debugger and you will not have any chance to inspect it and debug it from the inside.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;I leave it to you to decide how dangerous and error prone this can be.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;All your metaprogramming code, once verified that it is working, should be abstracted away into a set of more rigid mechanisms, with a precise name and meaning that can be put under test and documented.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;All these mechanisms should also support ways to output the code they generate and to probe the realtime looking for potential lexical conflicts.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;A simple example of 'controlled metaprogramming' is the attr_accessor mechanism in Ruby.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;When inside a class you declare a symbol as being an attr_accessor with&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;div style="border: 1.5pt double rgb(51, 153, 102); padding: 1pt 4pt; background: white none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; margin-left: 36pt; margin-right: 36pt;"&gt;     &lt;p class="MsoNormal" style="border: medium none ; padding: 0cm; background: white none repeat scroll 0%; margin-bottom: 6pt; text-align: justify; text-indent: 36pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt; &lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;; color: rgb(51, 102, 255);" lang="EN-GB"&gt;attr_accessor :my_symbol&lt;/span&gt;&lt;/p&gt;    &lt;/div&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;you are using a metaprogramming technique that generates a @my_symbol attribute, and both a getter and setter method for that attribute.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;b style=""&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;; color: green;" lang="EN-GB"&gt;Metaprogramming Protocols&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;Playing with the laws of reality can become a very messy thing very quickly; even more so when you are not the only one doing it.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;What happens if you override the method_missing mechanism of the Object class to implement your flavour of metaprogramming, only to discover that a library you were using was leveraging on the very same technique and you just interfered with it? &lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;You will soon start applying your meta-code as a sequence of patches that assume the presence or the absence of other libraries and become rigidly dependent on which libraries are present and ion their loading order.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;When you start playing with metaprogramming you will soon come to realise that you don't even need third party code to mess things up.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;You will probably perfectly manage to bring havoc on yourself within a few visits to the metaphysics underlying the Kernel and Object classes.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="margin-bottom: 6pt; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Comic Sans MS&amp;quot;;" lang="EN-GB"&gt;A Metaprogramming protocol could be the only way to get things in order at this point.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;A metaprogramming protocol offers an orderly way to access to some of the more dangerous and interference-prone mechanisms of the meta-layer.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;Rather than acting directly on the meta-mechanisms, you ask a meta-framework to do it for you, while specifying exactly what you need.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;The meta-framework will take care of registering your request and to handle the interference between similar requests coming from different libraries.&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;The meta-framework will usually act as a kind of multi-dispatching system with a call-back mechanism on its callers.&lt;/span&gt;&lt;/p&gt;  &lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-114030982367548681?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/114030982367548681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=114030982367548681' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114030982367548681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/114030982367548681'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-i.html' title='The Way of Meta - Part I'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113978848343649394</id><published>2006-02-13T00:54:00.000+01:00</published><updated>2006-02-13T00:54:47.573+01:00</updated><title type='text'>Digging into Ruby Symbols - O'Reilly Ruby</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;      &lt;p&gt;Another very simple intro to Ruby metaprogramming&lt;/p&gt;      &lt;p&gt;        Read more at        &lt;a href="http://www.oreillynet.com/ruby/blog/2005/12/digging_into_ruby_symbols_1.html#comments"&gt;www.oreillynet.com/ruby...&lt;/a&gt;      &lt;/p&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113978848343649394?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113978848343649394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113978848343649394' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113978848343649394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113978848343649394'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/digging-into-ruby-symbols-oreilly-ruby.html' title='Digging into Ruby Symbols - O&apos;Reilly Ruby'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113970757554655748</id><published>2006-02-12T02:26:00.000+01:00</published><updated>2006-02-12T02:26:15.593+01:00</updated><title type='text'>Haskell</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;      &lt;p&gt;I really should spend some time and learn the language. I did it at Uni but I didn't dig it at the time and I haven't really done much with it. As I get older and I start appreciating the functional flavour I should have a go at it.&lt;/p&gt;      &lt;p&gt;        Read more at        &lt;a href="http://perl.com/pub/a/2005/09/08/autrijus-tang.html?page=2"&gt;perl.com/pub/a/2005/09/...&lt;/a&gt;      &lt;/p&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113970757554655748?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113970757554655748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113970757554655748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113970757554655748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113970757554655748'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/haskell.html' title='Haskell'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113961465209638803</id><published>2006-02-11T00:37:00.000+01:00</published><updated>2006-02-11T00:37:32.100+01:00</updated><title type='text'>Ruby Social Club</title><content type='html'>Roberta and I have organised a nice evening amongst Ruby programmers in the Rome area on Thursday night.&amp;nbsp; It has been a good evening, spent at a pub in the centre of Rome drinking lager, eating nice food and talking about our experiences.&amp;nbsp; I will write more about it, but for the time being I just want to thank everybody that turned up.&amp;nbsp; It was good to meet up with so many good people sharing my very same interests. &lt;br&gt;&lt;br&gt;Here are a couple of web pages both in &lt;a href="http://ruby-it.org/pages/Primo+incontro+del+Ruby+Social+Club+a+Roma"&gt;italian&lt;/a&gt; and &lt;a href="http://www.rubygarden.com/ruby?RomeGroup"&gt;english&lt;/a&gt;, describing what we Ruby socialites are up to. &lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113961465209638803?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113961465209638803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113961465209638803' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113961465209638803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113961465209638803'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/ruby-social-club.html' title='Ruby Social Club'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113961412637243048</id><published>2006-02-11T00:28:00.000+01:00</published><updated>2006-02-11T00:28:46.380+01:00</updated><title type='text'>Beyond mainstream object-oriented programming</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;      &lt;p&gt;        Thanks to        &lt;a href="http://riffraff.blogsome.com/"&gt;Gabriele Renzi&lt;/a&gt;        for pointing this out on his blog.      &lt;/p&gt;      &lt;p&gt;This is a nice article on interesting thoughts around and beyond OOP.&lt;/p&gt;      &lt;p&gt;        Read more at        &lt;a href="http://jaortega.wordpress.com/2006/02/05/beyond-mainstream-object-oriented-programming/"&gt;jaortega.wordpress.com/...&lt;/a&gt;      &lt;/p&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113961412637243048?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113961412637243048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113961412637243048' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113961412637243048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113961412637243048'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/beyond-mainstream-object-oriented.html' title='Beyond mainstream object-oriented programming'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113944833939991187</id><published>2006-02-09T02:25:00.000+01:00</published><updated>2006-02-22T12:33:51.036+01:00</updated><title type='text'>Ruby Metaprogramming</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;This is an excellent OSCON presentation written by Vanderburg:  &lt;a href="http://www.vanderburg.org/Speaking/Stuff/oscon05.pdf"&gt;www.vanderburg.org/Spea...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After reading it, I have started publishing some draft excerpts on Ruby Metaprogramming from the &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/liquid-development-toc.html"&gt;'Liquid Development' book&lt;/a&gt; that I am writing:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-i.html"&gt;The Way of Meta - Part I&lt;/a&gt;&lt;br /&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-ii.html"&gt;The Way of Meta - Part II&lt;/a&gt;&lt;br /&gt;&lt;a href="http://liquiddevelopment.blogspot.com/2006/02/way-of-meta-part-iii.html"&gt;The Way of Meta - Part III&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113944833939991187?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113944833939991187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113944833939991187' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113944833939991187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113944833939991187'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/ruby-metaprogramming.html' title='Ruby Metaprogramming'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113911253670514581</id><published>2006-02-05T05:08:00.000+01:00</published><updated>2006-02-05T05:08:56.710+01:00</updated><title type='text'>Distilling Intent from Descriptions</title><content type='html'>&lt;span class="gmail_quote"&gt;&lt;/span&gt;This is a follow up to my &lt;a href="http://codesushi.blogspot.com/2005/12/maru-batsu-ii.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;previous posts&lt;/a&gt;  on the use of  &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-04-intents-stories-and-facts.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;    intents&lt;/a&gt;  to describe the game of maru batsu (well, maru-batsu sounds much cooler than tic-tac-toe :-)&lt;br&gt;&lt;br&gt;Every now and again I practice this small maru-batsu &lt;a href="http://blogs.pragprog.com/cgi-bin/pragdave.cgi/Practices/Kata" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;     kata&lt;/a&gt;  to see how my perception of things changes in time as I learn new ways of approching the encoding of intent.&lt;br&gt;&lt;br&gt;Something that I notice by reading my early posts is that, while the code is not bad, I tend to get too technical too early.&amp;nbsp; I know I shouldn't abstract too early.&amp;nbsp; I know I shouldn't create abstractions unless my intents prove that I need them (this process of spawning abstractions is described in  &lt;a href="http://liquiddevelopment.blogspot.com/2005/11/shape-code-after-language-ii.html" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Shape Code After Language&lt;/a&gt;).&amp;nbsp; &lt;br&gt;&lt;br&gt;Yet I always fall into the sin of over-abstraction.&amp;nbsp; It's not a big deal; sometimes it's just a matter of abstracting a Player class, because I feel it's a natural element of the maru-batsu discourse.&amp;nbsp; They taught us to make classes out of concepts, just in case we might need them. &lt;br&gt;&lt;br&gt;More I practice this kata, more I realise that I can do with less and less.&amp;nbsp; It feels pleasant to feel how much lighter the intents (and the code) become.&amp;nbsp; The Player doesn't need to be a class.&amp;nbsp; Most of the times it can simply be a symbol, and the way it is used can be made implicit by the context and illustrated by intents and stories. &lt;br&gt;&lt;br&gt;Today I will practice the kata one more time, in an iterative way.&amp;nbsp; Be patient, the code doesn't need to run as-it-is, as it is just a first exploratory attempt at designing intents.&lt;br&gt;&lt;br&gt;This is a first rough natural language description of maru batsu: &lt;br&gt;&lt;ul style="color: rgb(0, 0, 153); font-family: arial,sans-serif;"&gt;&lt;li&gt;maru batsu is played by two players on a 3x3 board&lt;/li&gt;&lt;li&gt;a player uses X marks, while the other uses O marks&lt;/li&gt;&lt;li&gt;the players take turns&lt;/li&gt;    &lt;li&gt; a player, in his turn, can put his mark on the empty squares of the board &lt;/li&gt;&lt;li&gt;a player that aligns three of his symbols on the board (Horizontally, vertically or diagonally) on the board wins.&lt;/li&gt;&lt;li&gt;if nobody has won and no new moves are possible, then it's a draw. &lt;/li&gt;&lt;/ul&gt;Then I get each statement in turn and I try to make it a bit more formal.&amp;nbsp; I will also put some comments of problems that I noticed only after the fact.&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;     &lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;maru batsu is played by two players on a 3x3 board&amp;quot;&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;     &amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.players.size == 2&lt;/span&gt;&lt;br style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.board.width      == marubatsu.board.height == 3 &lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;Why players.size when I could have n_of_players ?&amp;nbsp; Why did I feel the need to make explicit the inner structure of marubatsu?&amp;nbsp; This just creates just more coupling without any immediate additional benefit.&amp;nbsp; An  &lt;a href="http://en.wikipedia.org/wiki/Ethnographer" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;ethnographer&lt;/a&gt;  would probably point out that I am giving implicit importance to the concept of Player.&amp;nbsp; I am probably reifying&amp;nbsp; players because they belong to my everyday universe of discourse.&amp;nbsp; The same line of reasoning applies to  board.width.&amp;nbsp; These declarations of structure are actively implying a universe of games made out of boards and players.&amp;nbsp; While this might be a useful abstraction, it is an abstraction that I did not produce consciously.&amp;nbsp; It just seemed to be the 'natural' abstraction.&amp;nbsp; I erroneously perceived it as being 'the-way-the-real-world-is'. &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;a player uses X marks, while the other uses O marks&amp;quot; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect (marubatsu.symbol_of :player_A) == :X&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;     &amp;nbsp;&amp;nbsp;&amp;nbsp; expect (marubatsu.symbol_of :player_B) == :O&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt; &lt;br&gt;Here I resisted using strings to represent X and O.&amp;nbsp; They are symbols, they stand for things, for marks on the board.&amp;nbsp; They represent universal concepts.&amp;nbsp; They relate to the &lt;a href="http://en.wikipedia.org/wiki/Flyweight_pattern" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;     fly-weight structural pattern&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Yet I used '&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;symbol_of :player_A&lt;/span&gt;' rather than '&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;     symbol_of_player_A&lt;/span&gt;'.&amp;nbsp; Again, why did I feel the need to abstract this, as if I could want to play maru batsu with a variable number of players?&amp;nbsp; It's so hard to forget your symbolic perceptual stance and see things as they are.&amp;nbsp; I wonder if reading again  &lt;a href="http://www.drawright.com/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Drawing on the Right Side of the Brain&lt;/a&gt; could help me to get back to a more immediate reality.&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;     &lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;the players take turns&amp;quot;&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;     &amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.turn?.should_be :player_A&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.next_turn!&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;     &amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.turn?.should_be :player_B&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.next_turn!&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;     &amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.turn?.should_be :player_A&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt; &lt;br&gt;Again I implicitly assume a multitude of players.&amp;nbsp; Why not '&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;is_turn_of_player_A?&lt;/span&gt;'&lt;br&gt;&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;a player, in his turn, can put his mark on the empty squares of the board&amp;quot; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;   &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.turn?.should_be :player_A&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect marubatsu.board.has_mark_at? row=2, col=1&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.board.mark! row=2, col=1&lt;br&gt;     &amp;nbsp;&amp;nbsp;&amp;nbsp; expect (marubatsu.board.mark_at? row=2, col=1) == :X&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;    &lt;/span&gt; &lt;br&gt; &lt;/blockquote&gt;  &lt;br&gt; &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;Besides the over-complex designs that I have already pointed out, I have managed to do a couple of nice moves here.&amp;nbsp; I use the '&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;    row=2&lt;/span&gt;' parameter passing notation to specify the meaning of the number passed.&amp;nbsp; I also changed an initial '&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;marubatsu.board.mark_at?(row=2, col=1) &lt;/span&gt;' to '&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;(marubatsu.board.mark_at? row=2, col=1)&lt;/span&gt;'.&amp;nbsp; There is no semantic difference between the two notations, but I prefer the second one as I like to visualize what is inside the brackets as a single entity on which I do an operation.&amp;nbsp; In the former case the brackets were used to delimit a function parameters.&amp;nbsp; I tend to prefer to think in terms of entities than in terms of flows of data between functions.&amp;nbsp; This doesn't mean I don't like the functional style of programming.. mmh this is an ambiguous point I'll have to expand on in a future post on  &lt;span style="font-style: italic;"&gt;Stanzas &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;Dyamic Aggregates&lt;/span&gt;.&lt;br&gt;&lt;br&gt;Take note of the fact that the sentence &lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;   &amp;quot;a player, in his turn, can put his mark on the empty squares of the board&amp;quot; &lt;/span&gt;also implies that &lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;a player, in his turn, can NOT put his mark on the NON empty squares of the board&amp;quot;. &lt;/span&gt; I am going to state this intent as well.&lt;br&gt;&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;a player, in his turn, can NOT put his mark on the NON empty squares of the board&amp;quot;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;   &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.turn?.should_be :player_A&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.board.has_mark_at? row=1, col=1&lt;/span&gt;&amp;nbsp; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;   &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect_exception( :SquareUsedException ){&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.board.mark! row=1, col=1&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;   &lt;/span&gt; &lt;br&gt; &lt;/blockquote&gt;  &lt;br&gt; &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;To show that this intent holds, we state that we expect an exception in case we try to tick twice the same square of the maru batsu board.&amp;nbsp; From a technical point of view, it's nice to be able to state explicitly what kind of exception I am expecting here.&amp;nbsp; However, from a legibility point of view, something different might have been better.&amp;nbsp; Something like &amp;quot;cannot do  marubatsu.board.mark! ..., because :SquareUsed&amp;quot; might work even better!&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;  &amp;quot;a player that aligns three of his symbols (Horizontally, vertically or diagonally) on the board wins.&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;  &amp;nbsp;&lt;/blockquote&gt;&lt;/div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;  &amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board [:X, :O,:O],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-,:-],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-,:-]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.winner?&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.winner.should_be :player_A&lt;br&gt;  &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board [:O, :O,:O],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-,:-],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-,:-]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.winner?&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.winner.should_be :player_B &lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board [:X, :O,:O],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:-, :X,:-],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:-, :-,:X]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.winner?&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.winner.should_be :player_A &lt;/span&gt;  &lt;br&gt;&lt;/blockquote&gt; &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;br&gt;It might have been better to split this intent into three different intents, each one specifying one way to win (horizontal, vertical, diagonal).&amp;nbsp; Since I didn't want to have to play out a whole game to check winning conditions, I introduced a set_board verb that allows the injection of a board into the game.&amp;nbsp; I wonder if this is really a good thing.&amp;nbsp; From a TDD point of view it is a good thing since it introduces flexibility into the design, but this is not flexibility that is needed to describe the game play, so I am not so sure about it.&amp;nbsp; I am not sure about a valid alternative either, so I'll keep it for the time being. &lt;br&gt;&lt;br&gt;Another problem is that the examples are not exhaustive at all.&amp;nbsp; I do not show the whole range of winning combinations, and the combinations that I show are not shown for all players.&amp;nbsp; There should be 8 (3+3+2) winning combinations for each player, for a total of 16 combinations.&amp;nbsp; In this simple game I could even enumerate all of them, but what about more complex games?&amp;nbsp; How would you test moves in a game of chess? &lt;br&gt;&lt;br&gt;I like the way I set up the board using arrays, and how I resisted making up Board and Cell objects.&amp;nbsp; I don't like the fact that I tried to stay abstract using symbols and using :- to signify a blank cell.&amp;nbsp; It would have been much clearer to use strings.&amp;nbsp; Something like: &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board   &amp;quot;XOO&amp;quot;,&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;.X.&amp;quot;,&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;..X&amp;quot;&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;or even something like&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;  &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board &amp;lt;&amp;lt;-board&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;  &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; XOO&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .X.&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ..X&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  &lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;board&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;/blockquote&gt;&amp;nbsp;&lt;/div&gt;which would then have the burden to decode the multiline board string.&amp;nbsp; While this may be too heavy for this simple case, this approach could also be used to introduce small DLS-like dialects inlined within the code. &lt;br&gt; &lt;br&gt;As in a previous intent &lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;a player that aligns three of his symbols (Horizontally, vertically or diagonally) on the board wins.&amp;quot; &lt;/span&gt;  also implies the following converse intent:&lt;br&gt;&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;there is no winner if three equal symbols are not aligned (Horizontally, vertically or diagonally) on the board&amp;quot; &lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt; &lt;div&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&amp;nbsp;&lt;/blockquote&gt; &lt;/div&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board   [:-, :-,:-],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:-, :-,:-],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-,:-]&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect marubatsu.winner?&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board [:-, :X,:-],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:-, :O,:-],&lt;br&gt;  &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :O,:X]&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect marubatsu.winner?&lt;br&gt; &lt;/span&gt;&lt;/blockquote&gt;&lt;br&gt;but how can you 'prove' that there is no winner? how can you prove that there is a winner without enumerating all cases?&amp;nbsp; Do I need to prove things or do I simply need to enumerate some examples useful to elaborate working code? &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;if nobody has won and no new moves are possible, then it's a draw.&amp;quot; &lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt;  &lt;div&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&amp;nbsp;&lt;/blockquote&gt; &lt;/div&gt;  &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board   [:X, :O,:O],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:O, :X,:X],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :X,:O]&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect marubatsu.winner?&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.draw?&lt;/span&gt;&lt;/blockquote&gt;&lt;br&gt;again, should I enumerate all possible draws? &lt;br&gt;&lt;br&gt;should I also state all the following?&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;  &amp;quot;if someone has won then it's not a draw.&amp;quot;&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt;   &lt;div&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&amp;nbsp;&lt;/blockquote&gt; &lt;/div&gt;   &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board   [:O, :O, :O],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-, :-],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-, :-]&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect marubatsu.winner?&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect marubatsu.draw?&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;  &lt;span style="color: rgb(0, 153, 0); font-family: courier new,monospace;"&gt;&amp;quot;if nobody has won but new moves are possible, then it's not a draw.&amp;quot;&lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt;   &lt;div&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&amp;nbsp;&lt;/blockquote&gt; &lt;/div&gt;   &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; marubatsu.set_board   [:X, :O, :O],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:O, :X, :X],&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [:X, :-, :O]&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect marubatsu.winner?&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect marubatsu.draw?&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113911253670514581?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113911253670514581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113911253670514581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113911253670514581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113911253670514581'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/02/distilling-intent-from-descriptions_05.html' title='Distilling Intent from Descriptions'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113832395559889480</id><published>2006-01-27T02:05:00.000+01:00</published><updated>2006-02-03T02:14:51.126+01:00</updated><title type='text'>.c( whytheluckystiff )o. -- Seeing Metaclasses Clearly</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;      &lt;p&gt;        &lt;a href="http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html"&gt;This&lt;/a&gt;        is a useful tutorial on metaclasses by Why.&lt;/p&gt;&lt;p&gt;I wanted to do it all alone, but I will try to resist and see what is already available for me to build on.      &lt;/p&gt;      &lt;p&gt;    &lt;/p&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113832395559889480?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113832395559889480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113832395559889480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113832395559889480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113832395559889480'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/01/c-whytheluckystiff-o-seeing.html' title='.c( whytheluckystiff )o. -- Seeing Metaclasses Clearly'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113805256950163156</id><published>2006-01-23T22:42:00.000+01:00</published><updated>2006-01-23T22:49:20.276+01:00</updated><title type='text'>Online Community Building Tools</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;      &lt;p&gt;A friend recently called me up asking my help to enhance the ties of some activist groups he is touch with, by using the web.&lt;/p&gt;&lt;p&gt;I have been reading a bit about the web2.0, I had a quick brush with Ning and I mused on philosophical issues.&lt;/p&gt;      Now, it is the right time to act.&lt;br /&gt;&lt;br /&gt;I am pretty certain that what I want to do is      &lt;b&gt;to not&lt;/b&gt;      start some kind of website project from scratch.&lt;br /&gt;&lt;br /&gt;The group already has a small website, acting as a web frontend for the organization, but I would rather go for existing services or a mush-up rather then trying to run the infrastructure on our own.The other point is that, while I am very willing to spend time to create new stuff and put ideas together, I am not willing to put much effort into the maintenance.&lt;br /&gt;&lt;br /&gt;I also believe this is a chore that the community itself should take care of, learning how to live their own spaces and take care of them.I can see that on the web there are plenty of web2.0 apps, but what I see missing is some kind of glue to put together what I need into a single mushup.&lt;br /&gt;&lt;br /&gt;The lack of a single sign-on is particularly critical.&lt;br /&gt;&lt;br /&gt;We could go around this, by gathering user subscription requests through the main site and then automate subscriptions to all the different sites of the mush-up, making sure the usernames and passwords are unique.&lt;br /&gt;&lt;br /&gt;However this is both labour intensive and it raises some doubts from a privacy point of view.  What I am doing now is to look for a all-in-one community container.&lt;br /&gt;&lt;br /&gt;Something that provides single sign on to a number of basic services, which allows html customization and enhancements, and that allows easy administration of the system.&lt;br /&gt;&lt;br /&gt;These are some promising links that I have found:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://www.techsoup.org/resources/index.cfm?action=resource.view_summary&amp;amp;amp;amp;resourcelist_id=20"&gt;TechSoup&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://lt3.uwaterloo.ca/volunteer/resources.html"&gt;VolunteerNet&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.fullcirc.com/community/communitymanual.htm"&gt;Online Community Toolkit&lt;/a&gt;      (?)      &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;        &lt;a href="https://www.techsoup.org/resources/index.cfm?action=resource.view_summary&amp;amp;amp;resourcelist_id=20"&gt;      &lt;/a&gt;&lt;/p&gt;&lt;a href="https://www.techsoup.org/resources/index.cfm?action=resource.view_summary&amp;amp;amp;resourcelist_id=20"&gt;    &lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113805256950163156?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113805256950163156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113805256950163156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113805256950163156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113805256950163156'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/01/online-community-building-tools.html' title='Online Community Building Tools'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113778770603164692</id><published>2006-01-20T21:08:00.000+01:00</published><updated>2006-01-20T21:08:26.056+01:00</updated><title type='text'>Software Roadmap</title><content type='html'>I have started a number of small projects, both to explore ruby's capabilities and to play with some concepts that I found hard to express in other languages.&amp;nbsp; These projects are still in their infancy, so I haven't put them on rubyforge yet, but I plan to work on releasing them soon. &lt;br&gt;&lt;br&gt;The projects are:&lt;br&gt;&lt;ul&gt;&lt;li&gt;Intent: this one has been &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-04-intents-stories-and-facts.html"&gt;released&lt;/a&gt;.&amp;nbsp; It provides BDD-like statements on code, as an alternative to regular testing. &lt;br&gt;&lt;/li&gt;&lt;li&gt;Proze: it translates code - and intents in particular - to readable text.&amp;nbsp; It has been embedded in Intent.&lt;br&gt;&lt;/li&gt;&lt;li&gt;Agave: a small set of metaprogramming utilities&lt;br&gt;&lt;/li&gt;&lt;li&gt;Jazzgarden: 'smart' operations on objects - spreading commands over collections, taking 'slices' from object collections &lt;/li&gt;&lt;li&gt;SmartStores: implicit mapping of directory and file structures to object aggregates.&amp;nbsp; mapping of file types to classes.&lt;/li&gt;&lt;li&gt;Clay: a &lt;a href="http://liquiddevelopment.blogspot.com/2005/11/nooclay.html"&gt;nooclay &lt;/a&gt; substratum able to provide lots of shorthands and syntactic sugar, including object instantiation without the new method.&lt;br&gt;&lt;/li&gt;&lt;li&gt;Avocado: support for Concepts and Relationships representations&lt;br&gt;&lt;/li&gt;&lt;li&gt;Highrise: a small financial framework; yield curves, NPV, etc.. &lt;br&gt;&lt;/li&gt;&lt;li&gt;Gammaray: an easy access to an opengl subset to represent graph relationships in 3d&lt;/li&gt;&lt;li&gt;&lt;a href="http://codesushi.blogspot.com/2005/12/maru-batsu-ii.html"&gt;Marubatsu&lt;/a&gt;: an Intent-first implementation of tic-tac-toe, to be used as an Intent showcase &lt;br&gt;&lt;/li&gt;&lt;li&gt;Trickle: an Avocado and Gammaray based application that helps you design brainstorming sessions on a number of topics: plots, characters, ideas, etc..&lt;/li&gt;&lt;/ul&gt;I will show a couple of prozed intents from these projects.&amp;nbsp; If any of you is interested in any of them, let me know and I might focus my efforts on what becomes more popular and I will release it on rubyforge. &lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold; text-decoration: underline;"&gt;Agave&lt;/span&gt;&lt;br style="font-weight: bold;"&gt;&lt;br&gt;a small set of metaprogramming utilities&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;intent of &amp;quot;Generating text from a line of text and variations&amp;quot; &lt;br&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;Dear &amp;lt;title&amp;gt;&amp;nbsp; &amp;lt;person&amp;gt;&amp;quot; &lt;/span&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; substitute &lt;/span&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;&amp;lt;title&amp;gt;&amp;quot;&amp;nbsp; =&amp;gt; [&amp;quot;Mr&amp;quot;, &amp;quot;Dr&amp;quot;, &amp;quot;Mrs&amp;quot;],&lt;/span&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;&amp;lt;person&amp;gt;&amp;quot; =&amp;gt; [&amp;quot;Smith&amp;quot;, &amp;quot;Black&amp;quot;, &amp;quot;Grey&amp;quot;], &lt;/span&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; separator&amp;nbsp; =&amp;gt; &amp;quot;, &amp;quot;&lt;/span&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt; &lt;br style="color: rgb(255, 102, 0);"&gt;&lt;span style="color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; should be &amp;quot;Dear Mr&amp;nbsp; Smith, Dear Dr&amp;nbsp; Black, Dear Mrs&amp;nbsp; Grey&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="color: rgb(255, 102, 0);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;this is used as an helper to generate code for metaprogramming purposes. &lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold; text-decoration: underline;"&gt;Jazzgarden&lt;/span&gt;&lt;br style="font-weight: bold;"&gt; &lt;br&gt;smart operations on objects - spreading commands over collections, taking 'slices' from object collections&lt;br&gt;&lt;br&gt;easy creation of &lt;a href="http://patternshare.org/default.aspx/Home.DDD.ValueObjects"&gt;Value Objects&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;class Person  &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp; defined by name, surname, age &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;end&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;intent of &amp;quot;Reading attributes of an object using 'defined by'&amp;quot; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a person = Person new &amp;quot;Winnie&amp;quot;,&amp;quot;Pooh&amp;quot;,70&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; a person name should be &amp;quot;Winnie&amp;quot;&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a person surname should be &amp;quot;Pooh&amp;quot; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; a person age should be 70&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;existential quantification &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;intent of&amp;nbsp; &amp;quot;Verifying if exist any&amp;quot;&amp;nbsp;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect [1, 6, 10] exist any? |n| n&amp;gt;5&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect [1, 6, 10] exist any? |n| n&amp;gt;15&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;intent of&amp;nbsp; &amp;quot;Verifying at least one element is true&amp;quot;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; expect [true, true, false] any true? &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dont_expect [false, false, false] all true?  &lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;collective action using several alias forms&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; color: rgb(0, 153, 0);" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace;"&gt;people = [ &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;john&amp;quot;, &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;mike&amp;quot;, &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;Sam&amp;quot;&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;span style="font-family: courier new,monospace;"&gt;]&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;story &amp;quot;Turning people names to uppercase&amp;quot;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; people to upcase should be [&amp;quot;JOHN&amp;quot;,&amp;quot;MIKE&amp;quot;,&amp;quot;SAM&amp;quot;]&lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;intent of &amp;quot;Using shortcut form for collective action&amp;quot; &lt;/span&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; people / reverse&lt;/span&gt;&lt;span style="color: rgb(255, 102, 0);"&gt; &lt;/span&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; color: rgb(255, 102, 0);" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; should be [&amp;quot;nhoj&amp;quot;,&amp;quot;ekim&amp;quot;,&amp;quot;maS&amp;quot;]&lt;/span&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; color: rgb(255, 102, 0);" class="gmail_quote"&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex; color: rgb(255, 102, 0);" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; people all reverse everyone capitalize &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; should be [&amp;quot;Nhoj&amp;quot;,&amp;quot;Ekim&amp;quot;,&amp;quot;Mas&amp;quot;]&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;object slicing&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;intents &amp;quot;Object Slicing - sorting by property&amp;quot; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; people sort by name&amp;nbsp; every name &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; should be [&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;bill&amp;quot;,&amp;quot;john&amp;quot;,&amp;quot;mike&amp;quot;,&amp;quot;paul&amp;quot;,&amp;quot;sam&amp;quot;&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ]&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;and random picking... I will just give a prozed example here:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;people = [ &amp;quot;john&amp;quot;, &amp;quot;sam&amp;quot;, &amp;quot;mike&amp;quot;, &amp;quot;frank&amp;quot;]&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;people pick one&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; people pick two&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;people pick two different&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;br&gt; &lt;span style="font-weight: bold; text-decoration: underline;"&gt;SmartStores&lt;/span&gt;&lt;br&gt;&lt;br&gt;implicit mapping of directory and file structures to object aggregates.&amp;nbsp; mapping of file types to classes&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;def sample smart store&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; SmartStore new (&amp;quot;intent-files/data&amp;quot;) &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;end&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;story &amp;quot;Opening up an order&amp;quot;  &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp; repository = sample smart store&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp; repository map! [child, of &amp;quot;orders&amp;quot;] =&amp;gt; Order&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp; an order = repository&lt;/span&gt; &lt;br&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; order milan[&amp;quot;20050906&amp;quot;] &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retrieve&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp; expect an order,&amp;nbsp;&lt;br&gt; &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;to be &lt;/span&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;Order new&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;Chairs&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;gt;&amp;nbsp; 18,&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;Laptops&amp;quot;&amp;nbsp;&amp;nbsp; =&amp;gt;&amp;nbsp; 10,&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;Desks&amp;quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; =&amp;gt;&amp;nbsp; 7 &lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold; text-decoration: underline;"&gt;Clay&lt;/span&gt;&lt;br&gt;&lt;br&gt;all my intents for Clay are very poor.&amp;nbsp; I'll describe it another time.&lt;br&gt;what it does is to let you improvise the creation of objects and their attributes without needing to declare any class for them. &lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold; text-decoration: underline;"&gt;Highrise&lt;/span&gt;&lt;br&gt;&lt;br&gt;a small financial framework&lt;br&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(51, 204, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;story &amp;quot;Using Cashflows&amp;quot;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 204, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Let's now deal with cashflows&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &amp;nbsp;&lt;/blockquote&gt;&lt;/div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; with&amp;nbsp; Conventional discount = &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; continuously compounded yield&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; we&amp;nbsp; expect about 271.67748, as the&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; present value of&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Cashflow&amp;nbsp; [ &lt;/span&gt;&lt;/blockquote&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100 at 1 year ,  &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100 at 2 years , &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100 at 3 years&amp;nbsp; &lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ], &lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;span style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; with interest rate at&amp;nbsp;&amp;nbsp; 5 percent &lt;/span&gt;&lt;br&gt; &lt;/blockquote&gt;&lt;br&gt;The other stuff is a bit more articulate and I'll leave it for another post :-)&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113778770603164692?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113778770603164692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113778770603164692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113778770603164692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113778770603164692'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/01/software-roadmap.html' title='Software Roadmap'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113702774199975475</id><published>2006-01-12T02:02:00.000+01:00</published><updated>2006-01-12T02:02:22.006+01:00</updated><title type='text'>RSpec as a DSL</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;      &lt;p&gt;        I just saw        &lt;a href="http://blog.lavalamp.ca/articles/2005/12/06/rspec-as-a-dsl"&gt;Steven Baker's code&lt;/a&gt;        from        &lt;a href="http://rubyforge.org/projects/rspec/"&gt;RSpec&lt;/a&gt;        when pointed there by Victor Cosby.&amp;amp;nbsp; It looks a lot like my Intent framework.      &lt;/p&gt;      &lt;p&gt;I'll need to do some code reading here&lt;/p&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113702774199975475?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113702774199975475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113702774199975475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113702774199975475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113702774199975475'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/01/rspec-as-dsl.html' title='RSpec as a DSL'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113702662130564445</id><published>2006-01-12T01:43:00.000+01:00</published><updated>2006-01-12T01:43:41.313+01:00</updated><title type='text'>Modern Languages</title><content type='html'>&lt;div xmlns="http://purl.org/atom/ns#"&gt;      &lt;p&gt;Just some new languages to check out:&lt;/p&gt;      &lt;p&gt;        *        &lt;a href="http://boo.codehaus.org/"&gt;Boo&lt;/a&gt;        on codehaus      &lt;/p&gt;      &lt;p&gt;        *        &lt;a href="http://iolanguage.com/about/"&gt;Io&lt;/a&gt;        , a small language      &lt;/p&gt;      &lt;p&gt;        &lt;a href="http://boo.codehaus.org/"/&gt;      &lt;/p&gt;    &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113702662130564445?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113702662130564445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113702662130564445' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113702662130564445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113702662130564445'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/01/modern-languages.html' title='Modern Languages'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113625356012487948</id><published>2006-01-03T02:58:00.000+01:00</published><updated>2006-01-03T02:59:20.350+01:00</updated><title type='text'>Let the Code DRY - later on..</title><content type='html'>&lt;div style="text-align: justify;"&gt;I finished writing the first draft of the SnapshotEngine code that I wrote about in the previous post.  I produced it by copying and modifying snippets of code from the FactEngine, rather than subclassing it.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The result is much much clearer code.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;True, there is some duplication, but I am now in a better position to decide what can be abstracted.  I have detected a few common methods and I might put them into a common superclass or into a mixin utility module.  I might even decide to not abstract it.  The two classes could still develop in quite different ways and I may not want to tie them together yet.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113625356012487948?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113625356012487948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113625356012487948' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113625356012487948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113625356012487948'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/01/let-code-dry-later-on.html' title='Let the Code DRY - later on..'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113623662601200725</id><published>2006-01-02T22:17:00.000+01:00</published><updated>2006-01-02T22:45:07.386+01:00</updated><title type='text'>Let code DRY on its own: Duplicate, Scan, Refactor, Abstract</title><content type='html'>&lt;div style="text-align: justify;"&gt;Tonight I spent several hours trying to get a piece of code of the &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-04-intents-stories-and-facts.html"&gt;Intent&lt;/a&gt; framework working.  As usual these mistakes tend to be due to the wrong kind of laziness and to a false perception of coding economies.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;I had this set of classes handling 'facts' - a recording of certain chosen outputs of a piece of code - and I wanted to add a new feature called 'snapshots'.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;When you create a snapshot all the outputs of your program that would go to stdout are implicitly redirected to a file where they are stored and later used for a pretty raw form of regression testing.   Snapshots looked to me like a specialized form of Facts, so what I did was to inherit from my FactsEngine class a SnapshotsEngine class, and I started building on that.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;However as I was halfway through my top-down implementation (can I test first a test first framework? :-) I started realizing that the workflows of the two engines were not as similar as they seemed to me from an initial high level view.   There were a few annoying details that kept getting in the way.   Some state that should have been initialized, some step that was skipped, some more steps that needed to be added.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Soon enough the SnapshotsEngine had become an unreadable patch of the FactsEngine, that also had to be 'abstracted' to allow hooks for the SnapshotsEngine.   By the way, nothing worked anymore and I started downloading Komodo so that I could use a debugger.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As I am writing I start feeling that resorting to debugging is like an admission of failure.  I tried to don't repeat myself by going for inheritance, but I did it a bit too early.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;DRY - Don't repeat yourself - should be interpreted in a teleological sense.  The code should drift to a DRY state.  Starting out DRY is not always the best way to get it right, as it is far too easy to fall into upfront design and believe that you really know things that you don't know only because you are able to generate early abstractions.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I find that the following &lt;span style="font-weight: bold;"&gt;sequence &lt;/span&gt;works well to produce DRY code:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Duplicate&lt;/span&gt; - start out by creating your code by copy and paste.  Yes, I mean it.  Get the bits that work and produce something working. &lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Scan&lt;/span&gt; - perform an eye scan of the original code and the duplicated modified code.  Spot points of genuine semantic similarity and see if you can make the code more expressive by abstracting them out. &lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Refactor&lt;/span&gt; - apply a set of refactorings and Scans to extract the pieces of common code.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Abstract&lt;/span&gt; - look for opportunities of abstracting together the common pieces that you extracted as a superclass or as an aggregate/utility class.  Look for overall architectural and design patterns of composition and inheritance.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;What I found out is that a DRY, but bad abstraction is &lt;span style="font-weight: bold;"&gt;much much&lt;/span&gt; worst than duplicate code.  Duplicate code can still be abstracted in a clean way, and it can also be pretty easy on the eye even if it is quite verbose and repetitive.   Code that has been badly abstracted is obfuscated and hidden behind ad hoc abstractions and technical tricks that make it unreadable.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So, don't DRY your code.   Apply the &lt;span style="font-weight: bold;"&gt;DuScRAb&lt;/span&gt; sequence and let the code DRY on its own.&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113623662601200725?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113623662601200725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113623662601200725' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113623662601200725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113623662601200725'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2006/01/let-code-dry-on-its-own-duplicate-scan.html' title='Let code DRY on its own: Duplicate, Scan, Refactor, Abstract'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113598532576660697</id><published>2005-12-31T00:27:00.000+01:00</published><updated>2005-12-31T00:28:49.523+01:00</updated><title type='text'>Update: Table of Content</title><content type='html'>I have updated the &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/liquid-development-toc.html"&gt;Liquid Development ToC&lt;/a&gt; with the lastest posts.&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113598532576660697?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113598532576660697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113598532576660697' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113598532576660697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113598532576660697'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2005/12/update-table-of-content.html' title='Update: Table of Content'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113598289210028947</id><published>2005-12-30T23:48:00.000+01:00</published><updated>2005-12-30T23:52:54.836+01:00</updated><title type='text'>Tests as Storytelling</title><content type='html'>&lt;div style="text-align: justify;"&gt;If you look at tests as your main product and to code as just an implementation of the &lt;span style="font-weight: bold;"&gt;intent &lt;/span&gt;expressed by tests, then we start looking at tests with greater respect and attention.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Tests deserve refactoring.  They should be refined and honed so that intent is expressed exactly in one point. Well, ideally.. :-)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Tests should be &lt;span style="font-weight: bold;"&gt;read out as a story&lt;/span&gt;, as an explanation, as examples.&lt;br /&gt;&lt;div style="text-align: justify;"&gt;But they shouldn't be boring saying the same things over and over with little variations, in the hope of catching inconsistencies by brute force.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Reading through test should be like reading through an explanation of the system, showing you how to build up layers of abstraction and sometimes going deep in a concept, exploring all its facets.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113598289210028947?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113598289210028947/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113598289210028947' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113598289210028947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113598289210028947'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2005/12/tests-as-storytelling.html' title='Tests as Storytelling'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113572651049778571</id><published>2005-12-28T00:35:00.000+01:00</published><updated>2005-12-28T00:35:10.536+01:00</updated><title type='text'>Intent 0.4 - Intents, Stories and Facts</title><content type='html'>I have been keeping myself busy around christmas time.&amp;nbsp; I have corrected quite a few points of Intent and Proze, I have added a couple of examples, extended the functionalities and improved the layout.&lt;br&gt;&lt;br&gt;You can download  &lt;a href="http://rubyforge.org/projects/intent/"&gt;Intent-0.4&lt;/a&gt; from RubyForge.&lt;br&gt;&lt;br&gt;Once you have downloaded the package and made it available in ruby's load path you can run some of the samples in the demo directory.&lt;br&gt; &lt;br&gt;I have already detailed intent_of_mathematics in &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-03.html"&gt;another post&lt;/a&gt;, but it's worth to point out a couple of changes.&lt;br&gt;For a start I have added support for  &lt;span style="font-style: italic;"&gt;Facts&lt;/span&gt;.&amp;nbsp; A fact is a lazy developer's way of writing test.&amp;nbsp; You get some code that works and you literally save its context and its results, allowing you to freeze the implicit intent of this code. &lt;br&gt;&lt;br&gt;This is not really &lt;span style="font-style: italic;"&gt;intent-first&lt;/span&gt; development, but it is still a step towards capturing intent.&lt;br&gt;&lt;br&gt;The following code records a fact about divisions:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;fact!(&amp;quot;Result of Division&amp;quot;){&lt;/span&gt;&lt;br style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; given &amp;quot;area&amp;quot;,&amp;nbsp;&amp;nbsp; a = 100 &lt;/span&gt;&lt;br style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; given &amp;quot;height&amp;quot;, h = 5&amp;nbsp;  &lt;/span&gt;&lt;br style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt; &lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; follows &amp;quot;base&amp;quot;, a/h&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt; }&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;the fact get saved under the &amp;quot;facts&amp;quot; subdirectory as &lt;span style="font-style: italic;"&gt;Result_of_Division.fact.xml&lt;/span&gt;. The xml looks like this:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&amp;lt;fact id='&lt;span style="font-weight: bold;"&gt;Result of Division&lt;/span&gt;'&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style="font-weight: bold;"&gt;area&lt;/span&gt;&amp;gt;100&amp;lt;/&lt;span style="font-weight: bold;"&gt;area&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style="font-weight: bold;"&gt;height&lt;/span&gt;&amp;gt;5&amp;lt;/&lt;span style="font-weight: bold;"&gt;height&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;span style="font-weight: bold;"&gt;base&lt;/span&gt;&amp;gt;20&amp;lt;/&lt;span style="font-weight: bold;"&gt;base&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt; &lt;span style="font-family: courier new,monospace; color: rgb(0, 153, 0);"&gt;&amp;lt;/fact&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;I tried to make it readable and understandable on its own, so that even a different developer will be able to understand the intent of that fact. &lt;br&gt;&lt;br&gt;If the question mark of the &lt;span style="font-style: italic;"&gt;fact &lt;/span&gt;call gets changed to a question mark (or simply removed) &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;fact(&amp;quot;Result of Division&amp;quot;){&lt;/span&gt; ...&lt;br style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&lt;/blockquote&gt; &lt;span style="color: rgb(51, 51, 255); font-family: courier new,monospace;"&gt;&lt;/span&gt;&lt;br&gt;then we switch from recording the fact to verifying that the fact is still true.&lt;br&gt;&lt;br&gt;When I run a reality check on the intent (F5 in SciTe from the intent file) I get the following report: &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt; ---------- Reality checking Adding One ----------&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt;Consistent intent: ..1.. &lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt;Consistent intent: ..2..&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace;"&gt; &lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt;Consistent intent: ..3..&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt; &lt;span style="font-family: courier new,monospace;"&gt;---------- Reality checking Commutative Property of Addition ---&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt; &lt;span style="font-family: courier new,monospace;"&gt;Consistent intent: ..3..&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt; Consistent intent: ..5..&lt;/span&gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;which means that the early intents are ok.&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;---------- Reality checking Comparison - Lesser Than ----------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; Consistent intent: ..true..&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;**BROKEN** intent&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; expected &amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt;false&amp;lt;-&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; but got&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt;true&amp;lt;-&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; see: intent_of_mathematics.rb:14&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: rgb(255, 255, 102);"&gt;D:/apps/ruby/lib/ruby/1.8/intent/demo/intent_of_mathematics.rb:14:in &lt;/span&gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;which points out a broken intent and allows you to jump direcly to the offending intent code:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;blockquote&gt;&lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;intent_of(&amp;quot;Comparison - Lesser Than&amp;quot;) {&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect 0 &amp;lt; 1&lt;/span&gt;&lt;br style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;   &lt;span style="font-family: courier new,monospace; color: rgb(51, 51, 255);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="font-weight: bold;"&gt;expect 1 &amp;gt; 2&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;div&gt;Our division fact returns the following:&lt;br&gt;&lt;br&gt; &lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;---------- Reality checking Result of Division ---------- &lt;/font&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;Consistent intent: ..'area: 100'..&lt;/font&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; Consistent intent: ..'height: 5'..&lt;/font&gt;&lt;br style="color: rgb(255, 102, 0);"&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;Consistent intent: ..'base: 20'..&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt; we see that our saved fact has not been violated.&lt;br&gt;&lt;br&gt;The multiplication unfortunately is broken:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt;---------- Reality checking Result of Multiplication --&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt; &lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt;Consistent intent: ..'base: 20'..&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt; &lt;span style="font-family: courier new,monospace;"&gt;Consistent intent: ..'height: 5'..&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt; **BROKEN** intent&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expected &amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt;'area: 101'&amp;lt;- &lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; but got&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt;'area: 100'&amp;lt;- &lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; see: intent_of_mathematics.rb:46&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace; color: rgb(255, 102, 0);"&gt;&lt;font style="color: rgb(255, 102, 0);" size="1"&gt;&lt;span style="font-family: courier new,monospace;"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background-color: rgb(255, 255, 153);"&gt;D:/apps/ruby/lib/ruby/1.8/intent/demo/intent_of_mathematics.rb:46:in&lt;/span&gt;&lt;/span&gt;&lt;/font&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;/blockquote&gt;&lt;br&gt;as we can see the area is wrong.. &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;font size="1"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt; ------------ Prozing ------------&lt;/span&gt;&lt;br style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;prozing intent_of_mathematics.rb ... &lt;/span&gt;&lt;br style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;&lt;span style="color: rgb(255, 102, 0); font-family: courier new,monospace;"&gt;---------------------------------&lt;/span&gt;&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt; Then the intent gets prozed and produces a readable prozed file:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; require 'intent/all'&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;intent of &amp;quot;Adding One&amp;quot;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0 + 1&amp;nbsp; should be 1&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 + 1&amp;nbsp; should be 2&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 + 1&amp;nbsp; should be 3 &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;....&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; intent of &amp;quot;Recognising Illegal Operations&amp;quot; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect exception ZeroDivisionError &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when trying to calculate&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5 / 0&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;story &amp;quot;Calculating the Area of a Triangle&amp;quot; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; base&amp;nbsp;&amp;nbsp; = 10&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; height = 5&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; area&amp;nbsp;&amp;nbsp; = base * height / 2&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; expect 25, as area&lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;.... &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;fact &amp;quot;Result of Multiplication&amp;quot; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; given &amp;quot;base&amp;quot;,&amp;nbsp;&amp;nbsp; b = 20 &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; given &amp;quot;height&amp;quot;, h = 5&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; follows &amp;quot;area&amp;quot;, b*h + 1 &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;br style="color: rgb(0, 153, 0);"&gt; &lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;fact &amp;quot;Result of Division&amp;quot; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; given &amp;quot;area&amp;quot;,&amp;nbsp;&amp;nbsp; a = 100  &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; given &amp;quot;height&amp;quot;, h = 5&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="color: rgb(0, 153, 0);"&gt; &lt;span style="color: rgb(0, 153, 0);"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; follows &amp;quot;base&amp;quot;, a/h&amp;nbsp; &lt;/span&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;Intents are supposed to capture small grained intentions as a design device.&lt;br&gt;&lt;br&gt;Stories are descriptions of typical cross-functionality scenarios. &lt;br&gt;&lt;br&gt;Facts are frozen representations of implicit intent.&lt;br&gt;&lt;br&gt;In the next release of Intent I will also add &lt;span style="font-style: italic;"&gt;Snapshots&lt;/span&gt;, an even rougher way of capturing intents.&amp;nbsp; A snapshot will intercept and memorize a set of input and output streams (puts and gets) and will save them as unqualified facts. &lt;br&gt;&lt;br&gt;What I would like to do is to create a full development path that goes from raw implicit-intent snapshots to full fledged small granularity intents.&lt;br&gt;&lt;br&gt;I envision the following &lt;span style="font-style: italic;"&gt; sequence&lt;/span&gt;:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;snapshot --&amp;gt; fact --&amp;gt; story --&amp;gt; intent&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt; I was forgetting the final report.&amp;nbsp;&amp;nbsp; I'll adjust it a bit so that it fits on the web page:&lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt; &lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;--------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0); font-weight: bold;" size="1"&gt;Broken Expectations &lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; &amp;nbsp;* intent: Comparison - Lesser Than - #2: expected false, but was true&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;&amp;nbsp;* fact: Result of Multiplication - #3: expected area: 101, but was area: 100 &lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; ---------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0); font-weight: bold;" size="1"&gt;Broken Intents&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; ---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;&amp;nbsp;* Comparison - Lesser Than&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; ---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;---------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0); font-weight: bold;" size="1"&gt; Broken Facts&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt; &amp;nbsp;* Result of Multiplication&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: courier new,monospace; color: rgb(255, 102, 0);" size="1"&gt;---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;we also get a nice report for each category and an average of expectations per intent (a good proxy of intent granularity and expressiveness) &lt;br&gt;&lt;br&gt;&lt;blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; &amp;nbsp;----------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;Reality Checking&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; ---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; intents: 4&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; stories: 2&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; ---------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;passed intents: 3/4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; passed stories: 2/2&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; broken intents: 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; broken stories: 0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;----------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; facts: 2&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; expectations: 17&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; ----------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;passed facts&amp;nbsp; : 1/2&amp;nbsp;&amp;nbsp;&amp;nbsp; passed expectations: 15/17&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; broken facts&amp;nbsp; : 1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; broken expectations: 2&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; -----------------------------------------------------------&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; &lt;/font&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;expectations per intent: 2.3&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;-------------------------- &lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; powered by &amp;gt;&amp;gt;Intent&amp;lt;&amp;lt;&lt;/font&gt;&lt;br&gt;&lt;font style="font-family: times new roman,serif; color: rgb(255, 102, 0);" size="1"&gt; --------------------------&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;       Liquid Development 
-- The Art of Shaping Software --
&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/16766120-113572651049778571?l=liquiddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://liquiddevelopment.blogspot.com/feeds/113572651049778571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=16766120&amp;postID=113572651049778571' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113572651049778571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/16766120/posts/default/113572651049778571'/><link rel='alternate' type='text/html' href='http://liquiddevelopment.blogspot.com/2005/12/intent-04-intents-stories-and-facts.html' title='Intent 0.4 - Intents, Stories and Facts'/><author><name>kia</name><uri>http://www.blogger.com/profile/05750239458663051981</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-16766120.post-113572085611161986</id><published>2005-12-27T23:00:00.000+01:00</published><updated>2006-01-08T02:51:50.583+01:00</updated><title type='text'>More Behaviour Driven Design - Victor Cosby and Stacy Curl's work</title><content type='html'>&lt;div style="text-align: justify;"&gt;I have just found out Victor Cosby's &lt;a href="http://electricsheep.blogspot.com/"&gt;Dreaming of Electric Sheep&lt;/a&gt; where he gives examples of  &lt;a href="http://blog.daveastels.com/?p=53"&gt;Dave Astel's&lt;/a&gt; &lt;a href="http://electricsheep.blogspot.com/2005/10/dave-astels-behavior-driven-design.html"&gt;Behaviour Driven Design ruby framework&lt;/a&gt; (rSpec), providing some examples.  The rSpec framework goes for the junit-like approach where every class has an associated 'test' class (Spec here).  This offers some advantages over the approach that I used in &lt;a href="http://liquiddevelopment.blogspot.com/2005/12/intent-03.html"&gt;Intent&lt;/a&gt;.  For example you can introspect the Spec classes to gather some information on the name and number of specs that you are going to check.&lt;br /&gt;&lt;/div&gt; &lt;br /&gt;&lt;div style="text-align: justify;"&gt;I adopt a more free-flowing incremental kind of style, but many of my 'test' information are built only while the checks are executed.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;I have also seen some work done by &lt;a href="http://www.digitalcompulsion.com:5030"&gt; Stacy Curl&lt;/a&gt; on a &lt;a href="http://www.digitalcompulsion.com:5030/space/PicoUnit"&gt;unit test framework that uses PicoUnit&lt;/a&gt; to define tests in a pretty clean way. &lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;There are quite a few things that I like about Stacy's work.  For a start, while all the action happens within the context of tests, the code is shaped in such a way that it clearly expresses intentionality by using a reader-oriented declarative style.  I also like Stacy's approach to Test evolution.  You can see how the test evolves becoming richer and richer via intermediate steps that still make sense. &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Finally Stacy also starts reasoning about tests in terms of an 'imaginary language'.  I find this to be very forward thinking, as our basis for shaping knowledge should be based in language rather than specific programming languages.  This allows us to push the boundaries of our programming languages to handle more complex situations that could be easily described in human-oriented languages.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;While I use dependency injection, I don't use mocks the way Stacy does and this is probably the main difference with my work on intents.  I don't usually care about the interaction of my objects with other objects and I only care for direct results.  His mocks seem to check for the beh
