<?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-7500847127062768609</id><updated>2012-01-19T12:15:07.292-08:00</updated><category term='ruby'/><category term='others'/><category term='games'/><category term='challenges'/><category term='scala'/><category term='tools'/><category term='java'/><category term='dotNet'/><category term='software development'/><title type='text'>jc's blatherings</title><subtitle type='html'>pseudo random stuff and thoughts</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-1288589074127977140</id><published>2011-08-02T07:07:00.000-07:00</published><updated>2012-01-19T11:32:24.925-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>Best explanation of recursion I've ever seen</title><content type='html'>A CS professor once explained recursion as follows:&lt;br /&gt;&lt;pre class="prettyprint lang-css"&gt;A child couldn't sleep, so her mother told her a story about a little frog,&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; who couldn't sleep, so the frog's mother told her a story about a little bear,&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;who couldn't sleep, so the bear's mother told her a story about a little weasel...&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; who fell asleep.&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ...and the little bear fell asleep;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; ...and the little frog fell asleep;&lt;br /&gt;&lt;br /&gt;...and the child fell asleep.&lt;br /&gt;&lt;/pre&gt;&lt;span class="Apple-style-span" style="color: #111111; font-family: Verdana,Tahoma,'Arial Unicode MS',sans-serif; font-size: 12px;"&gt;For somebody who doesn't "get" recursion yet, this is not a bad map to start with. Stuff happens and when you get to an endpoint (base case in recursive talk) then&amp;nbsp;stuff happens in reverse order on the way back out as it all unwinds.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="color: #111111; font-family: Verdana, Tahoma, 'Arial Unicode MS', sans-serif; font-size: 12px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 10px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-1288589074127977140?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/1288589074127977140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2011/08/best-explanation-of-recursion-ive-ever.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1288589074127977140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1288589074127977140'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2011/08/best-explanation-of-recursion-ive-ever.html' title='Best explanation of recursion I&apos;ve ever seen'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-2211552298033468793</id><published>2011-07-19T11:04:00.002-07:00</published><updated>2011-08-02T07:09:54.353-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>The real basics or colour theory or what every one should know about colour.</title><content type='html'>Ever worked for days on a site just for the first friend that you show the final work comment something about this lines: "I think is missing something, but I don't know what"?... AHA, it has happened to me, and being me I promptly started enumerating feature after feature, you know the drill, trying to find out what she don't like 'cause that's why in the first place you showed her the work, to get some feedback, but anyway she goes on, "yes, yes, it's a pretty good site, but, I don't know, something is not right".&lt;br /&gt;&lt;br /&gt;Well, the look and feel is very important, let me stress that cause I tend to forget it every now and then, &lt;strong&gt;the look and feel is very important&lt;/strong&gt;, that is, the real user, your final goal, will be much more interested with the overall look and usability (don't start me on accessibility) of the site (or soft, or thing, or whatever) than with anything else, and is not polite to let them down in that area, not polite and not very professional of you. Ok, you can hire a designer, but really, who does that anymore?, i mean, in toy projects (that later, hopefully, scale to full web sites, you then get rich and retire early) and the like, this is not a big company and most often than not, you, as a developer (developers, has been said, must wear many hats) has to wear another hat, and that one is the designer hat, so, trust me on this, visual dessign is so important as everything else, if not more important, and colours are key to a good design.&lt;br /&gt;&lt;br /&gt;Today we'll be looking at the really basics of colour theory, something really cool that i just stumble upon last week. This post is about colours, i'm not talking about images, everybody knows that a picture says more than a thousand words, so, when you are designing your site you have to take images into account too, and sometimes those images impose the colours of the overall site. If you're following this, the idea to take home from this introductory chunks is that images and colours must be chosen really early in analysis, and look closely at that, in analysis i said and not in development, and i'm sticking to that, ja, opinioneted blog is this one! One more thing, layout is also very important, so, if you're lucky enough to have a board in your room start painting, if not, grab a piece of paper and start jotting layout ideas down. Following the masters, the guys at 37signals, I lately design my interfaces first and then go dirty on programming, the thing is, when the moment comes to write a form or some kind of menu, I want to has my colour scheme ready somewhere for me to get started.&lt;br /&gt;&lt;br /&gt;Anyway, back to colours. We'll talk first some theory, i know, i don't like theory either, just showme the code!!, but i think is very important, at least it is for me, being a complete newbie at this matters.&lt;br /&gt;&lt;br /&gt;Colours are divided into primary, secondary and tertiary. The primary colours are Red, Yellow and Blue (but you already knew that from elementary school, didn't you?), they are called primary 'cause you don't need to mix anything to get at them. Secondary colours are those that you obtain when you mix primary colours, they are: Orange (Red + Yellow), Green (Yellow + Blue) and Violet (Blue + Red). Tertiary colours are those that you obtain when you mix secondary colours, there are just so many to list here. They look like this:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Primary Colours&lt;/h2&gt;&lt;br /&gt;&lt;span style="background-color: red;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;code&gt;#FF0000&lt;/code&gt;&lt;br /&gt;&lt;span style="background-color: yellow;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;code&gt;#FFFF00&lt;/code&gt;&lt;br /&gt;&lt;span style="background-color: #0033cc;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;code&gt;#0033CC&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Secondary Colours&lt;/h2&gt;&lt;br /&gt;&lt;span style="background-color: #ff9900;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;code&gt;#FF9900&lt;/code&gt;&lt;br /&gt;&lt;span style="background-color: #00cc00;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;code&gt;#00CC00&lt;/code&gt;&lt;br /&gt;&lt;span style="background-color: #660099;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;code&gt;#660099&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Of the most importance are the tint, tone and shade of a given colour.&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;Tint&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;The resulting colour when white is added&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Tone&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;The resulting colour when gray is added&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Shade&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;The resulting colour when black is added&lt;/dd&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;Other not so important concepts, at least for me, are hue, saturation, and brightness.&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;Hue&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;The Hue is just the colour, fucking confusing, i know, but when people talk about hues they are talking about the colour.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Saturation&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;Is the amount of colour. A saturated color is vibrant, whereas a desaturated color looks dull and gray.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Brightness&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;Altering the brightness of a color can make the overall appearance of the color darker or lighter.&lt;/dd&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;Ok, before talking about the colour wheel or the schemes let's evoke some feelings.&lt;br /&gt;&lt;br /&gt;When you are choosing colours for your site you must think about the responses your choices will have on the users of the application. Choosing a wrong combination can be an abomination or can create confusion among your clients. Colours are cataloged into Warm, Cool and Neutral, though it is more a historical catalogue, it is one that is well accepted among good designers out there. Anyway, 'cause there is no app that exists without a context, you must beware your context and not follow this cataloging thingy to the letter, for example, while red is considered to be a warm colour, in Cuba and some other countries it signifies communism, so, if you're developing a site for a communist party (god helps you) or something, they will understand red as something else, so, in the same way that you internationalize text, currencies, dates, you must internationalize colours too, ja, it is getting complicated this, I know, but what you really want is to arouse emotions of your clients by means of colours. On the other hand it is important to notice that particular colors got they own meanings, for example, while yellow is a warm colour that evokes the sun or summer, it too can mean intelligence and happiness, in this regard google is your best friend, we're not going to cover some fuckin' color horoscope here.&lt;br /&gt;&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;Warm Colours&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;Are those colors that makes you think of warmth, sunlight, heat, summer, sun, fire, you get the idea. They are basically the following: Red, Yellow and Orange &lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Cool Colours&lt;/dt&gt;&lt;br /&gt;   &lt;dd&gt;This have a cooling or calming effect on people, they remaind you of spring, ice, or water. The principal ones are: Blue, Green and Purple&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Neutral Colours&lt;/dt&gt;&lt;br /&gt;   &lt;dd&gt;This are Black, White, Silver, Gray, Beige, and Brown and they are unifying colors. When used as background colours they help to accentuate the others.&lt;/dd&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-CcEZYp0xRJQ/TiXIzeujwnI/AAAAAAAAAEo/A7sMXqXmkfo/s1600/images.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5631127695843902066" src="http://4.bp.blogspot.com/-CcEZYp0xRJQ/TiXIzeujwnI/AAAAAAAAAEo/A7sMXqXmkfo/s320/images.jpg" style="cursor: hand; cursor: pointer; float: left; height: 143px; margin: 0 10px 10px 0; width: 143px;" /&gt;&lt;/a&gt;&lt;br /&gt;One other important thing to know is the colour wheel or, as we are working for a display, the RYB colour wheel (RYB stands for Red, Yellow, Blue, that you remember are the primary colours, and is the system used by computers). Taken from an &lt;a href="http://en.wikipedia.org/wiki/Color_wheel"&gt;article on Wikipedia&lt;/a&gt; wich is very complete and interesting and you should read right when you finish this one, the colour wheel is &lt;q&gt;An abstract illustrative organization of colour hues around a circle, that shows relationships between primary colours, secondary colours, complementary colours, etc&lt;/q&gt;. Well, let's just say that it helps a lot when you are working with colours.&lt;br /&gt;&lt;br /&gt;Ok, enough blather already, lets dive into some cool schemes.&lt;br /&gt;&lt;br /&gt;Colour schemes have been around for centuries, so, there is no need to reinvent the wheel, and although internet colours are a lot different from print colours, the principles are the same, the major difference being working with hex numbers. There are a lot of colour schemes out there (this I think, not really sure) but we'll be sticking here to only four of them and i will be explaining them in real simple terms, that is not because i'm a genius of education or anything, it is because they are really simple in concept and usage, you only need a colour wheel and you are up and running in no time. So, without further ado, here they are.&lt;br /&gt;&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;&lt;dt&gt;Monochromatic&lt;/dt&gt;&lt;br /&gt; &lt;dd&gt;Equates to one colour and all its tints, tones and shades. ex. yellow-orange (#FFCC00), tint (#FFF2BF), tone (#FFE680), shade (#B38F00). This is the simplest and easier to use scheme, you just select one colour and it and all is tints, tones and shades form the scheme, those are the colours you work with.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Complementary&lt;/dt&gt;&lt;br /&gt; &lt;dd&gt;You match up colours that lie directly opposite each other on the colour wheel. When you choose one colour and its opposite colour, you also include all the tints, tones and shades of both colours and those are the colours you work with. This scheme contains both warm and cool colours which provides contrast.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Triadic&lt;/dt&gt;&lt;br /&gt; &lt;dd&gt;You pick one colour and then pick two other colours that lie equidistant from each other around the circle on the colour wheel. This and all its tints, tones and shades are the colours you work with. This scheme also contains warm and cool colours, but one temperature will predominate. Usually, the temperature that will overshadow the other is the one that you chose on the front page.&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;Tetradic&lt;/dt&gt;&lt;br /&gt; &lt;dd&gt;Like the complementary scheme, only you use two complementaries that are equidistant. This and all its tints, tones and shades are the colours you work with. Note that this colour scheme can become quite complicated to work with, the more colours you choose the more complicated the colour scheme, that's plain and simple, just KISS it up.&lt;/dd&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;Although colour combinations may seem complicated, all colour schemes carry certain "rules". These guidelines make it easy to understand which colours work together to add interest and contrast to a Web site. I hope to have arisen some interest in you to dig deeper on this matter, if you do please tell me what you think about colours in general. Which scheme is the easiest to work with for you?, which is the hardest?, did your combination of colours make for a better overall design or do you think that this is a complete waste of time?&lt;br /&gt;&lt;br /&gt;Until next blather...&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-2211552298033468793?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/2211552298033468793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2011/07/real-basics-or-colour-theroy-or-what.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2211552298033468793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2211552298033468793'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2011/07/real-basics-or-colour-theroy-or-what.html' title='The real basics or colour theory or what every one should know about colour.'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-CcEZYp0xRJQ/TiXIzeujwnI/AAAAAAAAAEo/A7sMXqXmkfo/s72-c/images.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-5798564394546317188</id><published>2011-03-29T06:15:00.000-07:00</published><updated>2011-03-29T07:20:34.917-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><category scheme='http://www.blogger.com/atom/ns#' term='dotNet'/><title type='text'>MVC vs MVP</title><content type='html'>At my day job I'm working in a new .NET app (somebody kill me now, soon I'll write about .NET and why I don't like working on it), anyway, I'm just a programmer, you know, working in the trenches for so long now and enjoying it a lot... so, the guys in charge of architecture and shit like that (who needs an architect right) had decided to use MVC# (can I tell you a secret??, we are building a calculator with one or two other features) between a million other things, you know, in .NET you make &lt;a href="http://blog.expensify.com/2011/03/25/ceo-friday-why-we-dont-hire-net-programmers/"&gt;macdonalds&lt;/a&gt;. Ok, yesterday I was to see some stupid fellow that works here for him to explain me where he likes me to put the security features of our apps (yep, I'm building the security module, along with my coworker and good friend Kley) and he started babling and muttering about MVP and all the cool stuff that you can do with it, and the differences with MVC, of course, he didn't know a thing about it, as is usual here in Cuba, not his fault really, the man, if you ask me, has to get laid sometime soon for him to perform better at work. Anyway, here's the difference between MVC and MVP&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-AtXFFLZX7Jw/TZHhWniZdpI/AAAAAAAAAEA/HiOZAV6UpD0/s1600/Untitled.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 149px;" src="http://3.bp.blogspot.com/-AtXFFLZX7Jw/TZHhWniZdpI/AAAAAAAAAEA/HiOZAV6UpD0/s320/Untitled.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5589496391230125714" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ok, I couldn't help it... But really guys, what's the difference? They say that MVP is an evolution of MVC, but, is it?&lt;br /&gt;&lt;br /&gt;For me, they are both and architectural (hate the word, but couldn't came out with a replacement) decision for keeping the code organized and decoupled, meaning that the final goal of them both is to separate your presentation logic from your behind the scene business logic, the rest, guys, is an implementation detail. Ok, here is the basic idea, at least this is how I see it.&lt;br /&gt;&lt;br /&gt;In MVC, the model stores the data, the view is a representation of that data, and the controller allows the user to change the data. When the data is changed, all views are notified of the change and they can update themselves as necessary. In MVP instead of a Controller, we now have a Presenter, but the basic idea remains the same - the model stores the data, the view is a representation of that data and the presenter coordinates the application. So, the difference is that one is called MVC and the other MVP...&lt;br /&gt;&lt;br /&gt;Ok, if you really care, in MVP the Presenter part gets some extra powers, as in Popeye when he eats spinach. The Presenter's purpose is to interpret events and perform any sort of logic necessary to map them to the proper commands to manipulate the model in the intended fashion. Most of the code dealing with how the user interface works is coded into the Presenter, and that's a lot, 'cause it means that the Presenter and the view are tightly coupled with a direct link, yep, not a purist but like better the observer model as shown in MVC.&lt;br /&gt;&lt;br /&gt;Anyway, what do I know, just writing here some toughts, if you wanna get more insight a good place to start is always &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;wikipedia&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But why do I care? Well, it is important to know the why's of a pattern in order to use it for the good. With MVP in a desktop app you got the sangrail of applications, that is, 3-tier architecture, but that's for another ocassion. Of course, you got it if you use it for what it was intended in the first place, complicate things a little more and it all becomes a real maintenance nigthmare.&lt;br /&gt;&lt;br /&gt;Until next blather...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-5798564394546317188?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/5798564394546317188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2011/03/mvc-vs-mvp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/5798564394546317188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/5798564394546317188'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2011/03/mvc-vs-mvp.html' title='MVC vs MVP'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-AtXFFLZX7Jw/TZHhWniZdpI/AAAAAAAAAEA/HiOZAV6UpD0/s72-c/Untitled.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-2797297912134535708</id><published>2011-03-16T08:14:00.000-07:00</published><updated>2012-01-19T11:54:08.710-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dotNet'/><title type='text'>dotNet Hell</title><content type='html'>Well, at work I'm starting a new project and for that they've chosen the infamous .NET framework. Here's the thing, I'm the guy in charge of the security module rigth now and for that I have chosen Rhino.Security, we were already using NHibernate and all that. It's been a hell so far, only the configuration took me about one week of intense work (ok, I'm new to this .NET ecosystem but come on, who in the world writes a lib that is just plain hard to configure?, been working a lot in java and ruby and never seen this hell before). Anyway, for what is worth I'm posting today a quick tip that really made my head roll around in zig zags all day long. The problem was introducing the NHibernate Integration Facility on what already was a spaghetti hell of config code. You see, to configure Rhino.Security at one point, actually before creating the session factory you has to write:&lt;pre class="prettyprint"&gt;&lt;br /&gt;  Security.Configure(cfg, SecurityTableStructure.Schema);&lt;br /&gt;&lt;/pre&gt;where "cfg" is an instance of NHibernate.Cfg.Configuration, and ohh, if you want the schema generated by NHibernate using "hbm2ddl" (seems like a C name, god, those guys can't even name things well) and who doesn't in testing?, well, you too need a "cfg" object. The problem, of course, is that when you are using "Castle NHibernate Integration Facility" you don't have an easy access to that object (ok, when you see the solution further down you'll say that it wouldn't be any easy, but I had to use reflector in order to see the source and figure out the fix, in .NET even the docs sucks, sorry guys, that's how I feel, hate it very fuckin' much, and ohh, don't get me started about VisualStudio, from 1 to 10 I give it 1, jeje).&lt;br /&gt;Ok, still can't get up and running with Rhino.Security, think I'll spend all day working on that madness, so, let's resume this short post. It seems that the NHibernate.Cfg.Configuration objects are registered into whatever container you are using along with the factories, that is, one configuration and one factory for each element declared in the configuration .xml file 'cause with NHibernate Integration Facility you can declare many factories, and use multiple dbs, that's in the spirit of enterprise architecture we all know and hate from java. For example, if you got something like this:&lt;pre class="prettyprint"&gt;&lt;br /&gt; &amp;lt;facilities&amp;gt;&lt;br /&gt;     &amp;lt;facility id="nhibernate" type="Castle.Facilities.NHibernateIntegration.NHibernateFacility, Castle.Facilities.NHibernateIntegration"&amp;gt;&lt;br /&gt;       &amp;lt;factory id="nhibernate.factory"&amp;gt;&lt;br /&gt;         &amp;lt;settings&amp;gt;&lt;br /&gt;           &amp;lt;item key="connection.provider"&amp;gt;&lt;br /&gt;             NHibernate.Connection.DriverConnectionProvider&lt;br /&gt;           &amp;lt;/item&amp;gt;&lt;br /&gt;           &lt;br /&gt;         &amp;lt;/settings&amp;gt;&lt;br /&gt;       &amp;lt;/factory&amp;gt;&lt;br /&gt;     &amp;lt;/facility&amp;gt;&lt;br /&gt;   &amp;lt;/facilities&amp;gt;&lt;br /&gt;&lt;/pre&gt;you can get at the configuration object with code like this:&lt;pre class="prettyprint"&gt;&lt;br /&gt;  NHibernate.Cfg.Configuration cfg = container.Resolve&lt;nhibernate.cfg.configuration&gt;("nhibernate.factory.cfg");&lt;/nhibernate.cfg.configuration&gt;&lt;br /&gt;&lt;/pre&gt;ja, pretty easy he, if at least they had documented it...&lt;br /&gt;until next post and stay away from .NET all you can...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-2797297912134535708?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/2797297912134535708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2011/03/dotnet-hell.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2797297912134535708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2797297912134535708'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2011/03/dotnet-hell.html' title='dotNet Hell'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-3494621628311641769</id><published>2011-02-15T09:58:00.000-08:00</published><updated>2011-02-15T10:08:56.305-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>If only I could fly</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-LwLwy8no4jk/TVq_vFYEMoI/AAAAAAAAADY/6B5IKhz6cSU/s1600/flying%2Bpig.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 291px;" src="http://1.bp.blogspot.com/-LwLwy8no4jk/TVq_vFYEMoI/AAAAAAAAADY/6B5IKhz6cSU/s320/flying%2Bpig.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5573978304442282626" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;This is a quick, dirty and post drunk post that I'm feeling like writing. Lot's of thoughts lately, for example: are you modernist or postmodernist, I, myself can't be any ists (ism?), it just sounds too fuckin' smart for my taste, but just to be clear on that, if I had to choose I choose, well, whatever, just let me dream sometimes and maybe I dream I can fly. Anyway, I'm divagating now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Need to install new software for my brain, can't go on like this, my story (yep, every life is a story) is getting so bloddy bored ultimatly that sometimes I wish I could fly, and you know, take off and reach the point of no returning. As the saying goes, don't look back, ever, and most of all, don't look back in anger (well yes, it is a song not a saying but I'm so lazy right now that don't want to go to the delete key in my keybord). You see, I used to love writing the story of my life, but ultimately everything is so messed up and I'm not growing. We all know that for a good story the character must grow, situations are just sugar, the real story is how the character reacts and grows in the face of it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's the thing. Normally I has an objetive OS running on my brain, but sometimes some little sucking and freaking viruses get to my kernel with subjetive logic and it all gets messed up, you know, the dreaded blue screen that we all know and hate (just for the record my brain IS NOT running windows in any of it's flavors, I just wanted to make an analogy). The matter, of course, is that those little malware feels so native in my OS that I don't notice them and sometimes, even when I notice, I don't run my homegrown AntiVirus, 'cause man, so fuckin' good they feel.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, hacking my mind will take time, in the meantime I just wanted to remind myself that I'm most objective than not. Do I need an OS upgrade or someting? would my brain be running some freaking object oriented OS instead of a functional one?. Anyway, it just seem so freak at this point, REALLY WANT TO FLY, but that very thought is a subjective one...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;pd. right now I'm laughing loud in my mind, really laughing very freaking loud up there, somewhere.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-3494621628311641769?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/3494621628311641769/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2011/02/if-only-i-could-fly.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/3494621628311641769'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/3494621628311641769'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2011/02/if-only-i-could-fly.html' title='If only I could fly'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-LwLwy8no4jk/TVq_vFYEMoI/AAAAAAAAADY/6B5IKhz6cSU/s72-c/flying%2Bpig.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-5062595279305519426</id><published>2011-01-18T08:28:00.001-08:00</published><updated>2011-01-18T08:47:55.626-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'></title><content type='html'>A quick post to say to all that I'm back. It's been a long time since I don't post anything in here but I've been working in lots of things and internet at work it's been a real headache, anyway, I'm back and I'll be posting again real soon, for whoever reads this, that is.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, lets put some thoughts in here, 'cause I can't leave without actually posting anything, internet is back, I'll write something quick and navigate a little around to see what's up out there, in... not much.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The other day someone told me that I have a talent for programming and some things relating with technology and computers. Ok, it is good to hear that (more so coming from a pretty girl) but it got me thinking about that a little.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's what I think, talent is overrated, that's the ugly truth folks, get used to it and get over. If you multiply all the hours I've been sitting at a pc by all the readings-study-whatever then you can get a real number for all my talent, and I think that's the truth for almost anybody out there. Talent is good, I think, but talent alone just takes you so far, to get farther you need to work really hard in whatever your endeavour is, and after that, work harder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;until next blather...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-5062595279305519426?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/5062595279305519426/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2011/01/quick-post-to-say-to-all-that-im-back.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/5062595279305519426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/5062595279305519426'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2011/01/quick-post-to-say-to-all-that-im-back.html' title=''/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-923331265095609888</id><published>2010-08-19T12:28:00.000-07:00</published><updated>2010-08-19T12:46:08.699-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>hard times, lazy times</title><content type='html'>I've been real lazy this few past weeks, I know that no one reads this but still I wanted to apologize (at least to myself) for not posting anything in so long a time. The thing is that I've been only reading Cuban authors and in matters completely unrelated to software development and programming. Anyway, don't mind me, everyone has it's moments (and this is clearly not one of mine, but it soon be over). I would like to share with you the first strophe of one of my favorites Cuban writers: Virgilio Piñera in his superb poem The Whole Island (La Isla en Peso)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;The curse of being completely surrounded by water condemns me to this café table.&lt;/div&gt;&lt;div&gt;If I didn’t think that water encircled me like a cancer I’d sleep in peace.&lt;/div&gt;&lt;div&gt;In the time that it takes the boys to strip for swimming &lt;/div&gt;&lt;div&gt;twelve people have died of the bends.&lt;/div&gt;&lt;div&gt;When at dawn the woman who begs in the streets slides into the water,&lt;/div&gt;&lt;div&gt;precisely when she’s washing a nipple,&lt;/div&gt;&lt;div&gt;I resign myself to the stench of the harbor,&lt;/div&gt;&lt;div&gt;to her jacking off the sentry every night&lt;/div&gt;&lt;div&gt;while the fish sleep. A cup of coffee won’t dispel the fantasy&lt;/div&gt;&lt;div&gt;that once I lived in edenic innocence.&lt;/div&gt;&lt;div&gt;What caused the change?&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;See, I've been asking myself that very same question in the past couple of weeks...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Until next blather, with some programming, of course...&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-923331265095609888?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/923331265095609888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/08/hard-times-lazy-times.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/923331265095609888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/923331265095609888'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/08/hard-times-lazy-times.html' title='hard times, lazy times'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-7480464244408459629</id><published>2010-08-06T08:04:00.000-07:00</published><updated>2012-01-19T12:00:37.170-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>Prisoner's Dilemma</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Game_theory"&gt;Game Theory&lt;/a&gt; is a branch of math with practical applications in economy, biology, sociology, psychology, and others. It examines the strategic behavior of players that interact and take decision in a given context with formal stimulus (effectively the game rules) and are motivated by utility maximization knowing beforehand that the other players are rationals. The final utility (points) acquired by each player depends on the actions chosen by the other players. In this context, Game Theroy analices situations in which appear a conflict of interests. The goal of this analysis is to find out the optimal options to get the desired results given the circumstances. If this sound familiar (and forgive me the technical chat) is because you are living (as everyone else, of course) so, to maximize your income is good to take a look at Game Theroy, you know, life is like a big game we're playing every single day, and we, too, are competing against others.&lt;br /&gt;&lt;br /&gt;In this post we'll be looking at the &lt;a href="http://en.wikipedia.org/wiki/Prisoner%27s_dilemma"&gt;Prisioner's Dilemma &lt;/a&gt; problem wich is an example of a game in which is important the analsys of the strategic behavior where there is some mutual dependency between the players, that is to say, in this kind of games, one must take into account the other player(s) possible behavior. Before we get into that let me warn you, read this at your own risk, 'cause this is my personal blog I reserve to myself the right to blather of whatever crosses my mind, this is probably rant, so you are warned. Let's look at some initial concepts.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Game&lt;/b&gt;&lt;br /&gt;In Game Theroy, &lt;i&gt;game&lt;/i&gt; refers to a special kind of conflict in which participate a given number of individuals or groups. This individuals or groups are known by &lt;i&gt;the players&lt;/i&gt;. In every game it must exist some kind of rules that enforces the conditions for the game to begin, define the possible legal moves in every phase of the game, define the number of moves that constitute a complete game and the posible results when the game is over.&lt;br /&gt;&lt;b&gt;Play&lt;/b&gt;&lt;br /&gt;A &lt;i&gt;play&lt;/i&gt; defines how a game progreses between phases, this is, from the initial option to the final move of the game.&lt;br /&gt;&lt;b&gt;Gain&lt;/b&gt;&lt;br /&gt;The result of a game is some assignation of final utilities. The &lt;i&gt;gain&lt;/i&gt; or result defines what happens when the game is over. It is important to mention that there exists a balance result or gain if neither of the players can improve her gain given that the other players do not modify her strategies. The result of a given game can be represented by a &lt;a href="http://en.wikipedia.org/wiki/Payoff_matrix"&gt;matrix of results&lt;/a&gt; which represents the possibilities of every player and the game results given the options chosen by every one of them.&lt;br /&gt;&lt;b&gt;Strategy&lt;/b&gt;&lt;br /&gt;A &lt;i&gt;strategy&lt;/i&gt; is a list with optimal options for every player in any moment of the game. We say that a player has a strategy when she takes into account the reactions of the other players to make the decision.&lt;br /&gt;&lt;br /&gt;There are some &lt;a href="http://en.wikipedia.org/wiki/List_of_games_in_game_theory"&gt;kind of games&lt;/a&gt;   that Game Theroy takes into account, in this post we are interested in simultaneous games (which is the prissioner dilemma kind of game). Simultaneous games are those in which the players move at the same time or disclaim the previous moves of the other players. In this kind of games, the strategy must suppose wich is the best move for every player, that is to say, every player must think what to do if she is the other player. The rules of execution are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Choosing of the dominant strategy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Remove the dominated strategy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Find the &lt;a href="http://en.wikipedia.org/wiki/Nash_equilibrium"&gt;Nash Equilibrium&lt;/a&gt;. If it doesn't exists, the better move is to become unpredictable 'cause any repetitive behaviour can be exploited by the other players&lt;/li&gt;&lt;/ul&gt;So, let's get on with the Prisioner's Dilemma game. This game is ascribed to &lt;a href="http://en.wikipedia.org/wiki/Albert_W._Tucker"&gt;Albert W. Tucker&lt;/a&gt; and has been heavily studied by Game Theory because it constitutes a model of conflits that appear again and again in society. It is used as an example of the classical conflict between both individual and collective interests of those who make decisions, and to justify the beneficts of colaboration. In this game, it is implied that every player, individually, is trying to maximize his profit without taking into consideration the other player result. The classical problem goes like this:&lt;br /&gt;&lt;blockquote&gt;Two suspects are arrested by the police. The police have insufficient evidence for a conviction, and, having separated the prisoners, visit each of them to offer the same deal. If one testifies for the prosecution against the other (defects) and the other remains silent (cooperates), the defector goes free and the silent accomplice receives the full 10-year sentence. If both remain silent, both prisoners are sentenced to only six months in jail for a minor charge. If each betrays the other, each receives a five-year sentence. Each prisoner must choose to betray the other or to remain silent. Each one is assured that the other would not know about the betrayal before the end of the investigation. How should the prisoners act?&lt;/blockquote&gt;Every prisioner can opt to collaborate with the other, asserting that the partner is unjustifiably in jail, or can choose to defect, accusing the other of the commited crime. The matrix that represents the options of the game and its possible outcomes is the following:&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt; &lt;tbody&gt;&lt;tr&gt;   &lt;th&gt;&lt;/th&gt;   &lt;th&gt;Prisoner B Stays Silent&lt;/th&gt;   &lt;th&gt;Prisoner B Betrays&lt;/th&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;th&gt;Prisoner A Stays Silent&lt;/th&gt;   &lt;td&gt;Each serves 6 months&lt;/td&gt;   &lt;td&gt;Prisoner A: 10 years&lt;br /&gt;&lt;br /&gt;Prisoner B: goes free&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;   &lt;th&gt;Prisoner A Betrays&lt;/th&gt;   &lt;td&gt;Prisoner A: goes free&lt;br /&gt;&lt;br /&gt;Prisoner B: 10 years&lt;/td&gt;   &lt;td&gt;Each serves 5 years&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Working with this matrix, let's analyze every possible option and the consequential results. To accomplish this we'll suppose that the only goal of any of the suspects is minimize its penalty, which is to say that both suspects are completely selfish :).&lt;br /&gt;&lt;br /&gt;Every suspect has two options, cooperate with the accomplice and remain silent or betray the accomplice and confess. The important thing to notice is that the result of every election depends on the election of the accomplice, the problem, of course, is that they can't know beforehand what the election of the accomplice will be, in other words, each one of the suspects must choose her option without knowing what the other has choosed.&lt;br /&gt;&lt;br /&gt;Let's see how the &lt;i&gt;Prisioner A&lt;/i&gt; reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If my accomplice choose to betray I must choose to betray too (5 years of imprisonment is better than 10)&lt;/li&gt;&lt;li&gt;If my accomplice choose to cooperate I must betray (to go free is better than 6 months of imprisonment)&lt;/li&gt;&lt;/ul&gt;As can be seen, betray is a dominant strategy for both players, as, no matter the election of the accomplice, always one's penalty is minimized when betraying. However, this result is not optimum, 'cause if both of them betray they both recibe a large conviction (5 years). This is the point of the dilemma.&lt;br /&gt;&lt;br /&gt;From the point of view of the optimal interest of the set of both suspects, the choise that leads to the best result is that they both cooperate 'cause in this way both of them carry out the minimal possible penalty. This is the optimal result of the group and any other decision worsens the outcome for it. However, if the suspects follow individual and selfish interests, they both get a long sentence.&lt;br /&gt;&lt;br /&gt;There is another version of the dilemma (The iterated Prisoner's Dilemma) in which is posible to punish the accomplice if she has betrayed you. In this version it is possible to reach a cooperative result. Here, the dominant strategy is "Tit for Tat" wich consists in cooperate in the first iteration and then choose the strategy choosen by the other in the previous move. However, this is not the optimal result either. The study of the results obtained by this version of the game has shown that the selfish strategies tended to be worse in the long run, in the other hand, collaboration strategies tended to be better, and this with respect to self interest.&lt;br /&gt;&lt;br /&gt;Ok, enough blather for one day. We had seen that in problems like the Prissioner's Dilemma (there are lots of them in real live), always an optimal result is obtained if the players look for the group benefit and not the self benefit. However, in most of this situations, always a suboptimal result is obtained 'cause the players act in a selfish manner, damaging the others and in the process damaging themselves.&lt;br /&gt;&lt;br /&gt;Until next blather...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-7480464244408459629?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/7480464244408459629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/08/prisoners-dilemma.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/7480464244408459629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/7480464244408459629'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/08/prisoners-dilemma.html' title='Prisoner&apos;s Dilemma'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-8582964097236483069</id><published>2010-07-28T12:52:00.000-07:00</published><updated>2012-01-19T11:59:59.162-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><title type='text'>Fake Fake Fake</title><content type='html'>One of the things I personally has to thank ruby (and the dynamic language thingy) is how I, more and more, automate things. Everyone knows that automating things is what a computer is good at, but, in my early days as a programmer (initially I refuse to write code in anything else than assembly language, then C / C++, eventually Java and then all the doors where open :)) I didn't exploit the full power of my pc. Nowadays I find myself writing a lot of code to get some task done, you know, the usual suspects, scrapping text from books and docs, searching for things, empty my tmp folder, you name it, and it just feels right to go that way, but, back in my middle ages, I wasn't completly taking advantage of my computer.&lt;br /&gt;&lt;br /&gt;As a programmer, whenever we implement a feature, we have to test it. I don't talk here about unit tests, there's no replacement for well tested code, I'm talking about actual tests, you know, the real thing, like an integration test but live. This is important because more often than not you will be doing "live test" with the clients of your product. For example, in web development I always like to start mocking up my views so I can show it very early in development to my client for her acceptance (and of course, that way I can make a good interface before creating the improper software :)), and for that I need some dummy data to fill up my mock. In desktop development it happens too, for example, recently, during the days I was at the army preparing myself for a war that will never be (didn't I tell you about those days?, well, I can't, is state secret, but if you want to see some pictures and read some interesting rant you can go to my &lt;a href="http://cubastreetphotography.blogspot.com/"&gt;friend's blog&lt;/a&gt;, he's a very good photographer and you'll enjoy it very much, there's actually a post about his days at the army, like mine but not exactly so) I did a desktop soft in Java to manage every combatant in my battalion, it was a really dummy soft but I manage to make it interesting showing reports and a lot of other thingies. Anyway, at some point I needed some data to test my work. Of course I could have gone to my screens and start entering combatants until it pleases me, but, come on... This is what I came up with:&lt;pre class="prettyprint lang-java"&gt;&lt;br /&gt;package cu.jvillasante.batallon;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.util.Random;&lt;br /&gt;&lt;br /&gt;import cu.jvillasante.batallon.logic.Combatant;&lt;br /&gt;import cu.jvillasante.batallon.logic.CombatantCollection;&lt;br /&gt;import cu.jvillasante.batallon.logic.Serializer;&lt;br /&gt;&lt;br /&gt;public class TestData {&lt;br /&gt;  private static final char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();&lt;br /&gt;  private static final char[] numbers = "0123456789".toCharArray();&lt;br /&gt;  private static final String[] grades = { "GNRAL", "COR", "T. COR", "MY", "CAP",&lt;br /&gt;      "1ER. TTE", "TTE", "S. TTE", "1ER. SO", "SO", "S. INST", "SARG", "SOL" };&lt;br /&gt;  private static final String[] designations = { "Jefe de Batallón",&lt;br /&gt;      "2do Jefe de Batallón", "Jefe de Logística", "Jefe de Plana", "Jefe de Compañía 1",&lt;br /&gt;      "Jefe de Compañía 2", "Jefe de Compañía 3", "Jefe de Armas",&lt;br /&gt;      "Político del Batallón", "Armamento", "Pelotón de Aseguramiento", "Médico",&lt;br /&gt;      "SM Plana", "Jefe de Comunicaciones", "2do Jefe de Plana", "Ingeniero",&lt;br /&gt;      "Jefe de OIP", "Jefe de PCAEM", "Jefe de Pelotón de Zarpadores",&lt;br /&gt;      "Jefe de Exploración", "Jefe de Pelotón 1", "Jefe de Pelotón 2",&lt;br /&gt;      "Jefe de Pelotón 3", "Jefe de Pelotón de Armas" };&lt;br /&gt;  private static final Random random = new Random();&lt;br /&gt;  &lt;br /&gt;  public String name(final int max1, final int max2) {&lt;br /&gt;    if (random.nextBoolean())&lt;br /&gt;      return name(max1);&lt;br /&gt;    else&lt;br /&gt;      return composedName(max1, max2);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public String name(final int maxLength) {&lt;br /&gt;    final StringBuilder sb = new StringBuilder();&lt;br /&gt;    for (int i = 0; i &amp;lt; maxLength; i++)&lt;br /&gt;      sb.append(alphabet[random.nextInt(alphabet.length)]);&lt;br /&gt;    return capitalize(sb.toString());&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public String composedName(final int max1, final int max2) {&lt;br /&gt;    return name(max1) + " " + name(max2);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public String ci() {&lt;br /&gt;    final StringBuilder sb = new StringBuilder();&lt;br /&gt;    for (int i = 0; i &amp;lt; 11; i++)&lt;br /&gt;      sb.append(numbers[random.nextInt(numbers.length)]);&lt;br /&gt;    return sb.toString();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public String grade() {&lt;br /&gt;    return grades[random.nextInt(grades.length)];&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public String phone() {&lt;br /&gt;    final StringBuilder sb = new StringBuilder();&lt;br /&gt;    for (int i = 0; i &amp;lt; 8; i++)&lt;br /&gt;      if (i == 3)&lt;br /&gt;        sb.append("-");&lt;br /&gt;      else&lt;br /&gt;        sb.append(numbers[random.nextInt(numbers.length)]);&lt;br /&gt;    return sb.toString();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public String address() {&lt;br /&gt;    final StringBuilder sb = new StringBuilder();&lt;br /&gt;    sb.append(name(random.nextInt(numbers.length + 5)));&lt;br /&gt;    sb.append(" ");&lt;br /&gt;    sb.append(name(random.nextInt(numbers.length + 5)));&lt;br /&gt;    sb.append(" ");&lt;br /&gt;    sb.append(name(random.nextInt(numbers.length + 5)));&lt;br /&gt;    sb.append(" ");&lt;br /&gt;    sb.append(name(random.nextInt(numbers.length + 5)));&lt;br /&gt;    return sb.toString();&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public int number() {&lt;br /&gt;    return random.nextInt(10) + 10;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  private String capitalize(final String str) {&lt;br /&gt;    if (str.length() &amp;gt; 1)&lt;br /&gt;      return str.substring(0, 1).toUpperCase().concat(str.substring(1));&lt;br /&gt;    else&lt;br /&gt;      return str;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public static void main(final String[] args) {&lt;br /&gt;    final TestData td = new TestData();&lt;br /&gt;    final CombatantCollection cc = new CombatantCollection();&lt;br /&gt;    Combatant c = null;&lt;br /&gt;    for (final String designation : designations) {&lt;br /&gt;      c = new Combatant(td.grade(), td.name(td.number(), td.number()), td.composedName(td&lt;br /&gt;          .number(), td.number()), td.ci(), designation, td.phone(), td.address());&lt;br /&gt;      cc.add(c);&lt;br /&gt;    }&lt;br /&gt;    try {&lt;br /&gt;      Serializer.store(cc);&lt;br /&gt;      System.out.println("Data created...");&lt;br /&gt;    } catch (final IOException ex) {&lt;br /&gt;      ex.printStackTrace();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;A very brittle implementation if you ask me, but it gets the job done. As you see I generete names, numbers, addresses, phones, etc, and voila, just has to run this class to get a new data set to work with. Well, what's the point of all this, you'll be asking yourself (if anyone reads this, that is), I mean, WTH is this jc talking about?. You'll be right, I didn't wanted to show you that piece of code, well, I actually showed it to you, but that is not my point, my point is that now you, and me, and everybody else :), will agree that we need fake data, if not all the time at least most of it. &lt;br /&gt;&lt;br /&gt;Enter Lorem Ipsum. There's actually a &lt;a href="http://www.straightdope.com/columns/read/2290/what-does-the-filler-text-lorem-ipsum-mean"&gt;very cool article on what lorem ipsum mean&lt;/a&gt;, really, it is a very short but cool article, STOP READING AND GO READ THAT, THEN COME BACK HERE, but for our purposes, it means dummy data, fake data, and that is the name of the ruby gem (can't like it more, the gem name and also the ruby gem words together in the same sentence) that today we'll take a look at.&lt;br /&gt;&lt;br /&gt;For what is worth, I created a port of Faker (the ruby gem) to java, I know, it's better to use jRuby, but, if you want to fake some data and do it in java you can &lt;a href="https://gist.github.com/01baba43a29f9992c8a3"&gt;find a complete implementation written in java&lt;/a&gt; of the popular gem. I know that GitHub is better suited for this kind of sharing, but being a cuban guy I can't even create an account on GitHub, so, I'm using gist to share the code. Anyway, if you don't want to compile it or something, write me an email and I send you the jar with all the source included. Of important notice is that I just transcribed the ruby implementation to java, all the credit is for the initial authors of the gem, on the other hand, being new to the internet I don't know if that is actually legal. For what I gather the ruby gem is realesed with MIT-LICENSE, so, if anyone finds this offensive or something please, drop me a line and let me know.&lt;br /&gt;&lt;br /&gt;Back to earth, from java land I mean (who uses java anymore :), just kidding) with the ruby gem you can do very interesting things, let's fire up irb and found some of them:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;gt;&amp;gt; irb&lt;br /&gt;&amp;gt;&amp;gt; require 'faker'&lt;br /&gt;=&amp;gt; true&lt;br /&gt;&amp;gt;&amp;gt; Faker::Address.zip_code&lt;br /&gt;=&amp;gt; "66461"&lt;br /&gt;&amp;gt;&amp;gt; Faker::Address.country&lt;br /&gt;=&amp;gt; "Mali"&lt;br /&gt;&amp;gt;&amp;gt; Faker::Address.street_address&lt;br /&gt;=&amp;gt; "3057 Austin Spur"&lt;br /&gt;&amp;gt;&amp;gt; Faker::Internet.email&lt;br /&gt;=&amp;gt; "asa@kuvalis.ca"&lt;br /&gt;&amp;gt;&amp;gt; Faker::Lorem.sentence&lt;br /&gt;=&amp;gt; "Odit vitae quis atque tempora eos reprehenderit corrupti."&lt;br /&gt;&amp;gt;&amp;gt; Faker::Lorem.paragraph&lt;br /&gt;=&amp;gt; "Dolore est nihil et asperiores. Aut quisquam soluta nobis dolores fuga. Culpa neque quis a voluptas ducimus qui nihil sint. Eum soluta sit est vitae."&lt;br /&gt;&amp;gt;&amp;gt; Faker::Name.name&lt;br /&gt;=&amp;gt; "Sigurd Hudson"&lt;br /&gt;&amp;gt;&amp;gt; Faker::PhoneNumber.phone_number&lt;br /&gt;=&amp;gt; "1-975-016-4522 x7741"&lt;br /&gt;&amp;gt;&amp;gt;&lt;/pre&gt;Well, almost any kind of data you can generate. Before leaving you alone I share my rake task (fake_data.rake) to load some fake data in the db. Imagine you are doing a blog (I know, another!!!) and you has a User model and, what else, a Post model:&lt;pre class="prettyprint lang-ruby"&gt;&lt;br /&gt;require 'faker'&lt;br /&gt;&lt;br /&gt;namespace :db do&lt;br /&gt;  desc "Fill database with some fake autogenerated data"&lt;br /&gt;  task :populate =&amp;gt; :environment do&lt;br /&gt;    Rake::Task['db:reset'].invoke&lt;br /&gt;    make_users&lt;br /&gt;    make_posts&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def make_users&lt;br /&gt;  50.times do |n|&lt;br /&gt;    name  = Faker::Name.name&lt;br /&gt;    email = Faker::Internet.email(name)&lt;br /&gt;    password  = "password"&lt;br /&gt; User.create!(:name  =&amp;gt; name,&lt;br /&gt;              :email =&amp;gt; email,&lt;br /&gt;     :password =&amp;gt; password&lt;br /&gt;     :password_confirmation =&amp;gt; password)&lt;br /&gt;     &lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def make_posts&lt;br /&gt;  User.all.each do |user|&lt;br /&gt;    50.times do&lt;br /&gt;      content = Faker::Lorem.sentence(5)&lt;br /&gt;      user.posts.create!(:content =&amp;gt; content)&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;Anyway, something about those lines, clearly you must take care about your validations, if 'name' or 'email' are suppose to be unique you must use something more robust as factory_girl (I recently discovered that the gem is named like that because the &lt;a href="http://www.imdb.com/title/tt0432402/"&gt;film of 2006&lt;/a&gt;, cool people everywhere in ruby land). The point is that from now on, anytime you need some fake data in your app (or life for that matter) you know where to get it.&lt;br /&gt;&lt;br /&gt;Until next blather... I assure, next one will be more interesting.&lt;script language="javascript" type="text/javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-8582964097236483069?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/8582964097236483069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/fake-fake-fake.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/8582964097236483069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/8582964097236483069'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/fake-fake-fake.html' title='Fake Fake Fake'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-1791685613139873798</id><published>2010-07-20T07:52:00.000-07:00</published><updated>2010-08-06T08:26:35.143-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>Programmers are not cool in girl's eyes</title><content type='html'>&lt;div&gt;This was part of a talk with a friend earlier today. It's a fact, programmers are not popular in girl land, and all I will say in my defense is that it is a real shame, I mean, the programmers I know, the good ones of course, are very cool people and small talk is always a joy with them. But let's get to the post of today, clearly my friend got a point in what she said so, this is what I think on the matter.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You see, in the beginning was the command line and there's no girl that likes the command line. No, seriously, when you heard the word "cool" or "creative" (for me the diference is only slang) what type of profession spring to mind?, maybe painters, photographers, writers, musicians, even graphical designers and street racers, but programmers are out of the question. Nevertheless, programmers has the potential to be creative too and come up with ideas and concepts that will impact other people thinking and even feelings. In this respect I think that there are two major motives that makes something or someone "cool", how he or she approaches beauty and how much fun they have. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You see, programming is often paired with mathematics and most people don't find beauty in it. First of all, beauty is in the eye of the beholder, I'm sure, even when I'm not one of them, that a lot of people find beauty in math, I mean, I've heard histories about the balance of an equation, and if that is not beauty, well, I don't know what it is, I will not go any further in that direction, sufficiently to say that beauty is everywhere, just because someone don't see it doesn't mean it isn't there. In programming we talk about beautiful code, beautiful design, and we pursue beauty in every respect. We, as programmers know that the code we write is primary for people to read and just incidentally for a computer to understand, and since people, normal people I mean, like beauty, we must give it to them, so, in the end we try to write the most beautiful code that we are capable of, and when we do it, we feel a lot of pride for it, and most important, we call it elegant, beautiful code, not some piece of algorithm or engineer thingy. Oh, almost forgot, some programmers make an entire carrer, a successful one, without having even to open a book of math to refresh some concept, programming isn't about math, is a mistake people do.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;About the having fun question, well, is something that you must actually do to understand, but we has a lot of fun in our profession, you know, where were you (hypothetical reader) without things like facebook, twitter, gmail or yahoo, myspace, and the list keeps growing, so, if anyone think we work under pressure or we don't really enjoy what we do, well, think again...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Closing this 10 minutes blather, I think programmers could be cool too, they are shaping the future (I'm included too, how cool is that uh?), but which will you remember, Andy Warhol, Quentin Tarantino, John Lennon or Jamie Zawinski (I like others programmers actually but I wanted to share my favorite coder-hacker), yes I like Warhol, and I'm a programmer, so, we are doomed pal, let's get over it and start doing some cool programming work...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-1791685613139873798?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/1791685613139873798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/programmers-are-not-cool-in-girls-eyes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1791685613139873798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1791685613139873798'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/programmers-are-not-cool-in-girls-eyes.html' title='Programmers are not cool in girl&apos;s eyes'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-2311625764284004329</id><published>2010-07-15T08:48:00.000-07:00</published><updated>2012-01-19T12:04:10.490-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><title type='text'>Beautifull Ruby</title><content type='html'>Ruby itself and it's community are known to embrace the TIMTOWTDI (There Is More Than One Way To Do It) acronym and all in all it is a good thing. Other languages are less permissive (Phyton for instance) but Matz wanted us to do our job in the best way that we think we can do it, rather than he's own way. Nevertheless, there are some idioms that steadily the community around the language are growing and those are called the "Ruby Way" of doing things. I'm not in the taking sides business so I really think that we, as developers, have to do what is easier for us to do rather than looking the "Ruby Way" of doing it but even so there are some idioms that are worth knowing when we are developing. In this post I'll walk you through an example of what Ruby can do for you, and ultimately, what you can do for the users of your code, yeah, including yourself as the first user of the code you write.&lt;br /&gt;&lt;br /&gt;For this example we are going to tackle a simple problem that over and over keeps showing in our everyday work. We are going to build some configuration stuff, this will not be production code nor robust code for that matter, what I'm trying to do here is see (myself included, I found out that I learn better when I write about what I'm learning...) how we can simplify our apis making use of the powers of the Ruby language.&lt;br /&gt;&lt;br /&gt;Normally when I start working in a new feature or project I first enter the drawing phase where I jot down in a piece of paper what I'm trying to build, this takes 15 to 20 minutes and I recommend you do the same in your own projects, jotting is fun (children enjoy it too :)) and is incredible how you gain in understanding of the problem at hand. In this post however we'll take another road, instead of the normal course of events that I do everytime (jotting, writing initial tests, probing things out) we'll start with a simple class that will manage the configuration stuff of our project. Here's some code:&lt;pre class="prettyprint"&gt;&lt;br /&gt;require 'forwardable'&lt;br /&gt;&lt;br /&gt;class Config&lt;br /&gt; extend Forwardable&lt;br /&gt;&lt;br /&gt; def initialize(file = 'path_to_file')&lt;br /&gt;   @configurations ||= {}  # normally initialized from a file&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def_delegators :@configurations, :[]=, :[]&lt;br /&gt;&lt;br /&gt; # Other methods here, :read_from_file, :save_to_file, etc...&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;config = Config.new&lt;br /&gt;config[:font]   = 'Arial'&lt;br /&gt;config[:width]  = 100&lt;br /&gt;config[:height] = 50&lt;br /&gt;&lt;br /&gt;puts config[:font]&lt;br /&gt;puts config[:width]&lt;br /&gt;puts config[:height]&lt;br /&gt;&lt;/pre&gt;Even so simple code looks good in Ruby, we are using the Forwadable module (see "lib/forwardable.rb") to forward calls to our hash so we don't have to write that boring code, you see, when you are writing less code to make something work you know that you are in the right road, a good programmer is a lazy programmer.&lt;br /&gt;&lt;br /&gt;Now, we are taking a shortcut here, this is the simplest configuration manager ever written, in a real application you'll want something more robust and maybe you are reading and writing to a database, anyway, it's a good start, following the DTSTTCPW (Do The Simplest Thing That Could Possibly Work) principle, it is a good start if there is one. Here's the important thing to notice, a few years ago, when I was a Java freak, I surely had written an immensely huge class with everything I could dream about a configuration manager will ever need. Today instead I had grown up and older :) and always strive for simplicity. Anyway, our config class is pretty good so far (the best part being that it's just 5 lines of very easy to understand code) but how we use it, well, I'm not so sure of that. You see, we have to create a new class with "Config.new", that, I think,  is redundant, I mean, we'll always need a Config instance if we ever want to config our app, and we'll ever need just one instance, well yes, We don't want everyone around creating instances of our little Config class. Enter the Singleton pattern, again, Ruby makes that easy too:&lt;pre class="prettyprint"&gt;&lt;br /&gt;require 'forwardable'&lt;br /&gt;require 'singleton'&lt;br /&gt;&lt;br /&gt;class Config&lt;br /&gt; extend Forwardable&lt;br /&gt; include Singleton &lt;br /&gt;&lt;br /&gt; def initialize(file = 'path_to_file')&lt;br /&gt;   @configurations ||= {}  # normally initialized from the file&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def_delegators :@configurations, :[]=, :[] &lt;br /&gt;&lt;br /&gt; # Other methods here, :read_from_file, :save_to_file, etc...&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;Config.instance[:font]   = 'Arial'&lt;br /&gt;Config.instance[:width]  = 100&lt;br /&gt;Config.instance[:height] = 50&lt;br /&gt;&lt;br /&gt;puts Config.instance[:font]&lt;br /&gt;puts Config.instance[:width]&lt;br /&gt;puts Config.instance[:height]&lt;br /&gt;&lt;br /&gt;Config.new # config.rb:25:in `&lt;main&gt;': private method `new' called for Config:Class (NoMethodError)&lt;/main&gt;&lt;/pre&gt;&lt;br /&gt;Well, we just added a line (include Singleton) to our little monster and everything works as a charm (see "lib/singleton.rb"), now we've got a single instance of the Config class, see the last line?, if we ever call "new" on "Config" we get an error, the way to access our instance is, yeah what else could be, the "instance" method that the "Singleton" module automagically added to our class. Anyway, we are just getting warm here, until now is all boiler plate code (but cool still since we are in Ruby land) now is when things get interesting. You see, I'm still not happy with how the users of "Config" use (redundant?) my class, well, the class itself is far from being complete but is my own and I have all the time in the world to change it later, for now, I want to concentrate myself in the api I give to the world. The problem here, of course, is that our users had to know a little about our class to use it, you see, "Class.new" has it's problems, especially if we are talking about a singleton instance, but at least is the usual way to create an object and the way most people assume, now, with our little addition of the "Singleton" module, our users will have to know that the normal way of accesing our instance object is by the "instance" class method of the "Config" class, that's a shame and we are not being polite with them. On the other hand, it is always good having a single instance easily accesible, but after a talk with the server module crew, yeah we comunicate too, we know that for them configurations are set once, in the startup of the server, so, we can do better for those guys that are so an important in our company. Enter blocks, but first let's look at some rails code:&lt;pre class="prettyprint"&gt;&lt;br /&gt;ActionController::Routing::Routes.draw do |map| &lt;br /&gt; map.root :controller =&amp;gt; "pages"&lt;br /&gt; # more routes go here...&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;Well, rails is being polite with us, users of the framework. In the code above is where we define the routes of out rails app, imagine if you has to do something like "ActionController::Routing::Routes.instance[:root] = :controller =&amp;gt; 'pages'" for every route, it is just not boring, but it isn't very DRY (Dont Repeat Yourself) either, so, how we can do something like that?, here's how:&lt;pre class="prettyprint"&gt;&lt;br /&gt;require 'forwardable'&lt;br /&gt;require 'singleton'&lt;br /&gt;&lt;br /&gt;class Config&lt;br /&gt; extend Forwardable&lt;br /&gt; include Singleton &lt;br /&gt;&lt;br /&gt; def initialize(file = 'path_to_file')&lt;br /&gt;   @configurations ||= {}  # normally initialized from the file&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def_delegators :@configurations, :[]=, :[] &lt;br /&gt;&lt;br /&gt; def self.draw&lt;br /&gt;   yield(self.instance)&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; # Other methods here, :read_from_file, :save_to_file, etc...&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;Config.draw do |config|&lt;br /&gt; config[:font]   = 'Arial'&lt;br /&gt; config[:width]  = 100&lt;br /&gt; config[:height] = 50&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;Config.draw do |config|&lt;br /&gt; puts config[:font]&lt;br /&gt; puts config[:width]&lt;br /&gt; puts config[:height]&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;So, now we're talking :). Three lines of code after we got something good and sweet for our users to have. As you see we yield our instance to the block variable "config" and in the blok we can use that variable to set or read or call any methods we later add to the "Config" class. Oh, if you want to get rid of the "config" block variable you can do that with "instance_eval", but that will be another post on Metaprogramming in the future. Closing up, always take the time to think how your users will use your code, a good way of doing this is through TDD (Test Driven Development) but even if you are not using TDD you can always do better, expecially in Ruby being one of the cleanest languages out there. Ah, other thing, stop thinking about blocks in terms of iterators, they are so cool to be stereotyped. Hope you (whose "you", does anyone actually read this?, if so please leave a comment) like this.&lt;br /&gt;&lt;br /&gt;Until next blather...&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-2311625764284004329?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/2311625764284004329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/beautifull-ruby-ruby-itself-and-its.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2311625764284004329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2311625764284004329'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/beautifull-ruby-ruby-itself-and-its.html' title='Beautifull Ruby'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-2249770993852958772</id><published>2010-07-06T07:48:00.000-07:00</published><updated>2012-01-19T12:05:30.407-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='challenges'/><title type='text'>Project Euler's first four challenges</title><content type='html'>&lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt; is a series of challenging mathematical/computer programming problems that require some mathematical skills to solve. The challenges, however, are a very good starting point when you are learning a new programming language. Well, there are some very tough challenges there but all in all you can find lots of problems and always one of them will grab your attention. For what is worth I'm posting the solution for the first four challenges (initially I was going to post solutions for the first 5 challenges but I didn't found an easy way to solve challenge 5 :(, feel free to send me your solution if you solve it) so you can get the feel of the challenges and, hopefully, start doing your owns. The solutions are commented out so you can know how is done, also, some of them are solved in different ways (incidentally I was reading about Enumerators in Ruby when I stumble upon Project Euler), have fun and share your solutions with me.&lt;pre class="prettyprint"&gt;&lt;br /&gt;# If we list all the natural numbers below 10 that are multiples of 3 or 5, &lt;br /&gt;# we get 3, 5, 6 and 9. The sum of these multiples is 23.&lt;br /&gt;# &lt;br /&gt;# Find the sum of all the multiples of 3 or 5 below 1000.&lt;br /&gt;&lt;br /&gt;### Solution 1 (the easy way)&lt;br /&gt;sum = 0                                 # initialize sum to 0&lt;br /&gt;1000.times do |i|                       # iterate from 0 to 999&lt;br /&gt;  sum += i if i % 3 == 0 or i % 5 == 0  # add to sum only if required&lt;br /&gt;end&lt;br /&gt;puts sum                                # print the final sum&lt;br /&gt;&lt;br /&gt;### Solution 2 (ruby fu -- see the documentation for Enumerable#find_all and Enumerable#inject)&lt;br /&gt;puts (1...1000).find_all { |i|  i % 3 == 0 or i % 5 == 0 }.inject(0) { |sum, n| sum + n }&lt;br /&gt;&lt;br /&gt;# Solution 3 (using an enumerator)&lt;br /&gt;# we create an enumerator that generates numbers from 0 to 999 that are multiples of 3 or 5&lt;br /&gt;multiples = Enumerator.new do |y|&lt;br /&gt;  1000.times { |i| y &amp;lt;&amp;lt; i if i % 3 == 0 or i % 5 == 0 }&lt;br /&gt;end&lt;br /&gt;puts multiples.inject(0) { |sum, n| sum + n }  # sum all the numbers generated and print&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;# Each new term in the Fibonacci sequence is generated by adding the previous two terms. &lt;br /&gt;# By starting with 1 and 2, the first 10 terms will be:&lt;br /&gt;# &lt;br /&gt;# 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...&lt;br /&gt;# &lt;br /&gt;# Find the sum of all the even-valued terms in the sequence which do not exceed four million.&lt;br /&gt;&lt;br /&gt;# Solution 1&lt;br /&gt;i, j, sum = 0, 1, 0        # i and j are the first two fibonacci numbers, sum is initialized to 0&lt;br /&gt;while sum &amp;lt; 4_000_000      # iterate until the sum is less than 4 million&lt;br /&gt;  sum += i  if i % 2 == 0  # add to sum if the next fibonacci is even&lt;br /&gt;  i, j = j, i + j          # calculate next fibonacci&lt;br /&gt;end&lt;br /&gt;puts sum                   # print sum&lt;br /&gt;&lt;br /&gt;# Solution 2 (Using an enumerator)&lt;br /&gt;i, j, sum = 0, 1, 0                # i and j are the first two fibonacci numbers, sum is initialized to 0&lt;br /&gt;fibonacci = Enumerator.new do |y|  # an enumerator that generates fibonacci numbers&lt;br /&gt;  loop do&lt;br /&gt;    y &amp;lt;&amp;lt; i&lt;br /&gt;    i, j = j, i + j&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;while sum &amp;lt; 4_000_000                   # iterate until the sum is less than 4 million&lt;br /&gt;  next_fib = fibonacci.next             # get the next fibonacci number from the generator&lt;br /&gt;  sum += next_fib if next_fib % 2 == 0  # add to sum if next_fib is even&lt;br /&gt;end&lt;br /&gt;puts sum                                # print sum&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;# The prime factors of 13195 are 5, 7, 13 and 29.&lt;br /&gt;# &lt;br /&gt;# What is the largest prime factor of the number 600851475143 ?&lt;br /&gt;&lt;br /&gt;# One way to solve this challenge is to repeatedly divide by prime numbers (see http://amby.com/educate/math/2-1_fact.html)&lt;br /&gt;number, factor = 600_851_475_143, 2  # number is the number we are working with, factor is the smallest prime factor&lt;br /&gt;while number &amp;gt; 1                     # iterate while number is grater than 1&lt;br /&gt;  if number % factor == 0            # if factor divides number without remainder&lt;br /&gt;    number = number / factor         # do the division and save it to number&lt;br /&gt;  else                               # else&lt;br /&gt;    factor += 1                      # increment factor for next iteration&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;puts factor                          # print the factor, in this case it is the largest prime factor of the initial number&lt;/pre&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;# A palindromic number reads the same both ways. The largest palindrome made from &lt;br /&gt;# the product of two 2-digit numbers is 9009 = 91 x 99.&lt;br /&gt;# &lt;br /&gt;# Find the largest palindrome made from the product of two 3-digit numbers.&lt;br /&gt;&lt;br /&gt;# I think that being a palindrome number is more lexical property than a mathematical one, at&lt;br /&gt;# least I didn't found a way to know mathematically if a number is palindrome, so, I convert&lt;br /&gt;# the number to a String and check that.&lt;br /&gt;products = Enumerator.new do |y|  # An Enumerator that generates all the products of the problem&lt;br /&gt;  (100..999).each do |i|          # this enumerator effectively generates numbers of the form xxx * xxx&lt;br /&gt;    (100..999).each do |j|&lt;br /&gt;      y &amp;lt;&amp;lt; i * j&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;# select() the numbers that are palindrome from the enumerator (see Enumerable#select)&lt;br /&gt;# sort this numbers and print the last one wich at this point is the largest one&lt;br /&gt;puts products.select { |p| p.to_s == p.to_s.reverse }.sort.last&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Until next blather...&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-2249770993852958772?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/2249770993852958772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/project-eulers-first-four-challenges.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2249770993852958772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/2249770993852958772'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/07/project-eulers-first-four-challenges.html' title='Project Euler&apos;s first four challenges'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-6522552638023336460</id><published>2010-06-30T10:11:00.000-07:00</published><updated>2010-07-19T12:42:38.892-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='challenges'/><title type='text'>The Game of Life</title><content type='html'>&lt;div&gt;Hi there...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I haven't posted anything recently (not that anyone read this but...) because I was called up by the army and finally the mobilization is over. Actually I was writing a post about my experiences in it but I rather pass, you know, this is an odd country and one can get in trouble very easily. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, after my return to normal life I was reading stuff on the internet and found &lt;a href="http://ruby-challenge.rubylearning.org/"&gt;this&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="https://gist.github.com/f787d117565ed529c8a5"&gt;Here's my solution&lt;/a&gt; to the Game of Life challenge, hope you like it and enjoy it as much as I did writing it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Expect a new post soon, rigth now I'm still seeing enemies everywhere, you know, as Admiral Hornblower used to say, Any ship can be a minesweeper ...... once.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Until next blather...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note 2 days later: &lt;a href="https://gist.github.com/967c2235c85169f9673d"&gt;Here's an improved solution&lt;/a&gt; of the same challenge, now I take into account a folded board and do some minor changes...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-6522552638023336460?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/6522552638023336460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/06/game-of-life.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/6522552638023336460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/6522552638023336460'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/06/game-of-life.html' title='The Game of Life'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-3190781538355609215</id><published>2010-06-08T05:03:00.000-07:00</published><updated>2012-01-19T12:07:07.743-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><title type='text'>Build and install gems from gemspec files</title><content type='html'>Being a cuban developer I'm always fighting to stay current. I've got internet in at work (not in my house, no one I know does) but even at work I can't download anything, just navigate. In practical terms that means that I can't do something as simple as:&lt;pre class="prettyprint"&gt;&lt;br /&gt;  gem install factoy_girl  # install a gem from known repositories in the internet&lt;/pre&gt;and expect it to work, things just aren't that easy for me :(. So when I need a new gem I usually go to Github and download file by file, yes, view file after file in raw mode and save it to my hard drive. Last week I did that with a gem called factory_girl wich is a fixture replacement (yeah, you know how hard are fixtures to maintain in the long run) but once I got it all in my hard drive I had no clue how to install it, it wasn't a gem not a rails plugin. After some digging I found that you can build a gem if you have the gemspec file, so, if anyone is in the same position as me, I hope this save you some time.&lt;br /&gt;&lt;br /&gt;Here's how you do it, assuming you have all the files in a directory called factory_girl&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  cd factory_girl                # cd to the directory&lt;br /&gt;  gem build factory_girl.gemspec # build the gem file from the gemspec file&lt;/pre&gt;After that you get a gem file in the same directory from wich you run the build command, just install it and enjoy.&lt;pre class="prettyprint"&gt;&lt;br /&gt;  gem install factory_girl-1.2.5.gem  # install the gem you just build&lt;br /&gt;  gem list --local                    # check to see if it all worked out&lt;/pre&gt;How did I discover this?, actually it was very easy, just did &lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  gem --help&lt;/pre&gt;and one of the lines was&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  gem build package.gemspec&lt;/pre&gt;So, I did&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  gem help build&lt;/pre&gt;And this is the output&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;Usage: gem build GEMSPEC_FILE [options]&lt;br /&gt;&lt;br /&gt; Common Options:&lt;br /&gt;   -h, --help                       Get help on this command&lt;br /&gt;   -V, --[no-]verbose               Set the verbose level of output&lt;br /&gt;   -q, --quiet                      Silence commands&lt;br /&gt;       --config-file FILE           Use this config file instead of default&lt;br /&gt;       --backtrace                  Show stack backtrace on errors&lt;br /&gt;       --debug                      Turn on Ruby debugging&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; Arguments:&lt;br /&gt;   GEMSPEC_FILE  gemspec file name to build a gem for&lt;br /&gt;&lt;br /&gt; Summary:&lt;br /&gt;   Build a gem from a gemspec&lt;/pre&gt;So, the moral of this is, as ussualy is in software development, &lt;b&gt;GET TO KNOW YOUR TOOLS&lt;/b&gt;. &lt;br /&gt;Until next blather...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-3190781538355609215?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/3190781538355609215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/06/build-and-install-gems-from-gemspec.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/3190781538355609215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/3190781538355609215'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/06/build-and-install-gems-from-gemspec.html' title='Build and install gems from gemspec files'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-1661994140497888239</id><published>2010-06-04T06:02:00.000-07:00</published><updated>2012-01-19T12:07:42.672-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><title type='text'>Unscramble word game in ruby</title><content type='html'>Hello everyone, yesterday me and a friend don't really has much to do at work and we decided to play a game, of course, part of the game was writting one :), so I came up in almost no time with an unscramble in Ruby. It's a script actually with no much thought, no tests..., just a quick divertissement. Here I share the code with you all for when you get bored as we did yesterday.&lt;pre class="prettyprint"&gt;&lt;br /&gt;# unscramble - Picks a word, scrambles it, and asks the user to guess&lt;br /&gt;#    what the original word (or phrase) was.&lt;br /&gt;&lt;br /&gt;# return random word from file, I know, I know, reading everything just to return a single word...&lt;br /&gt;def read_random_word(word_file = 'words.txt', min_chars = 5)&lt;br /&gt;  words = []&lt;br /&gt;  File.open(word_file, 'r').each do |word|&lt;br /&gt;    words &amp;lt;&amp;lt; word.chomp if word.length &amp;gt;= min_chars&lt;br /&gt;  end&lt;br /&gt;  words[rand(words.length)]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# scrambles the word, return word scrambled&lt;br /&gt;def scramble_word(word)&lt;br /&gt;  result = []&lt;br /&gt;  word.each_byte do |byte|&lt;br /&gt;    result &amp;lt;&amp;lt; byte.chr&lt;br /&gt;  end&lt;br /&gt;  result.sort_by { rand }.join&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def initialize_game&lt;br /&gt;  $word = read_random_word&lt;br /&gt;  $scrambled_word = scramble_word($word)&lt;br /&gt;  $tries = 1&lt;br /&gt;  puts "You need to unscramble: #{$scrambled_word}"&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;STDOUT.sync = true   &lt;br /&gt;&lt;br /&gt;initialize_game&lt;br /&gt;&lt;br /&gt;loop do&lt;br /&gt;  print "Your guess(quit|next): "&lt;br /&gt;  answer = STDIN.gets.chomp&lt;br /&gt;  case answer&lt;br /&gt;  when /quit/ then break&lt;br /&gt;  when /next/ then initialize_game&lt;br /&gt;  else&lt;br /&gt;    if answer == $word&lt;br /&gt;      puts "*** You've got in #{$tries} tries! Well done!! ***"&lt;br /&gt;      initialize_game&lt;br /&gt;    else&lt;br /&gt;      $tries += 1&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;/pre&gt;That's all, have fun and until next blather.&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-1661994140497888239?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/1661994140497888239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/06/unscramble-word-game-in-ruby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1661994140497888239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1661994140497888239'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/06/unscramble-word-game-in-ruby.html' title='Unscramble word game in ruby'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-7315665354848792513</id><published>2010-05-28T11:39:00.000-07:00</published><updated>2012-01-19T12:09:07.881-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Introducing Scala - More about implicits</title><content type='html'>A coworker of mine have hear me talking to much about Scala lately so he is finally interested, in a marketing mood I remit him to my blog (well, I've given him all the doc I have about Scala and of course, my blog address when sometimes I rant a little about the language). After reading the implicits post he didn't get it, you know, people with a java background will call blasphemy things like that, but anyway I think it is not clear enough what is the problem that implicits are trying to solve if you read my post. A good argument he give me is that other than writing yet another math library who will need a '!' in class Int (converted or otherwise, yes, I told him how the ruby guys do things), well, that is not a very strong point, but he continues saying that if every class out there try to be everything to everybody then the class becomes too complex to be of any use. I think he really got a point there, In the math example I rather write a mixin (aka Trait) before doing an implicit conversion, I do that for the sake of api, yeah, beautiful apis and all that, but, still, sometimes implicits are the way to go. In this post I will be translating a great example found in the book The Ruby Programming Language by David Flanagan and Yukihiro Matsumoto (aka Matz), eventually, my goal is that you get to love implicits, not really love 'cause love is overrated :-), but that you get to know when implicits are the way to go.&lt;br /&gt;&lt;br /&gt;Imagine you need some kind of sequence to iterate over a set of values by an specified step. The following code defines an example class named Sequence:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;/**&lt;br /&gt;* This class represents a sequence of numbers characterized by the three&lt;br /&gt;* parameters from, to, and by. The numbers x in the sequence obey the&lt;br /&gt;* following two constraints:&lt;br /&gt;*&lt;br /&gt;*    from &amp;lt;= x &amp;lt;= to&lt;br /&gt;*    x = from + n * by, where n is an integer&lt;br /&gt;*/ &lt;br /&gt;class Sequence(from: Int, to: Int, by: Int) extends Iterable[Int] {&lt;br /&gt;  // This is the iterator required by the Iterable Trait&lt;br /&gt;  def elements = new Iterator[Int] {&lt;br /&gt;    var x = from&lt;br /&gt;    &lt;br /&gt;    def hasNext = x &amp;lt;= to&lt;br /&gt;    def next = { &lt;br /&gt;      val rtn = x&lt;br /&gt;      x += by&lt;br /&gt;      rtn&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  // Define the length method to return the number of values in the sequence&lt;br /&gt;  def length = if(from &amp;gt; to) 0 else (to - from) / by&lt;br /&gt;  &lt;br /&gt;  // Returns the n-th element of this sequence. The first element is at position 0.&lt;br /&gt;  def apply(n: Int): Option[Int] = {&lt;br /&gt;    require(n &amp;gt;= 0, "The index can't be negative")&lt;br /&gt;    &lt;br /&gt;    val v = from + n * by&lt;br /&gt;    if(v &amp;lt;= to) Some(v) else None&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  // Override arithmetic operators to return new Sequence objects&lt;br /&gt;  def *(factor: Int) = new Sequence(from * factor, to * factor, by * factor)&lt;br /&gt;  def +(offset: Int) = new Sequence(from + offset, to + offset, by) &lt;br /&gt;  &lt;br /&gt;  // ... many useful methods that most likely no one will never need ...&lt;br /&gt;}&lt;/pre&gt;Our class is pretty basic and very readable, the only thing that can bewilder you is that apply method, the comment says that it returna the n-th element of this sequence and you can call it like that, but Scala give us some syntactic sugar, if you call () with any object, behind the scenes Scala will call an apply method that matches the arguments passed, if defined, so, if you write sequence(4), scala will actually call sequence.apply(4). Arguably the convention is a little strange at first  but Scala goes a long way and is very much stable and consistent with it, even arrays have it, you don't get to say array[4] you have to say array(4) for getting the fourth element of an array. Anyway, some other people explain that much better than me, so go find a good explanation in google. This is how you use it:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;val s = new Sequence(1, 10, 2) // from 1 to 10 by 2's&lt;br /&gt;s foreach print                // prints "13579"&lt;br /&gt;println( s(s.length).get )     // prints 9 (see the Option return type of the method, that's why you must call get in it)&lt;br /&gt;val s1 = (s + 1) * 2           // from 4 to 22 by 4's&lt;br /&gt;s1 foreach print               // prints "48121620"&lt;/pre&gt;And that is all, pretty much basic sequence manipulation, but wait, where to is all of this getting us?, I mean, we're talking about implicits right?, how is this related with the title of today's blather. Let's see if we can get to that. The key feature of our Sequence class is its iterator, that's the elements method. If we are only interested in iterating over a sequence, there is no need to define the whole class (I know, everyone likes writing classes like that, at least that is what they teach us in school, you know, if something is needed, write a class, if you need something else, write a class, and keep writing classes the heck out of yourself for every little thing you may need. It is proven to be the right way of doing things, but stay with me a little longer), instead, we can simply write an iterator method that accepts the from, to and by parameters. So let's see that approach, we'll make it an object just for the joy of it.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;object Sequence { &lt;br /&gt;  def fromtoby(from: Int, to: Int, by: Int) = new Iterator[Int] {&lt;br /&gt;    var x = from&lt;br /&gt;    &lt;br /&gt;    def hasNext = x &amp;lt;= to&lt;br /&gt;    def next = { &lt;br /&gt;      val rtn = x&lt;br /&gt;      x += by&lt;br /&gt;      rtn&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Sequence.fromtoby(1, 10, 2) foreach print&lt;/pre&gt;So, an iterator like this makes it unnecessary to create a Sequence object to iterate a sequence of numbers, but the name of the method is quite long and its invocation syntax is unsatisfying. What we really want is a way to iterate a numeric Range by steps other than 1. Yes, Scala has a Range object and being at that, we don't really want to impose in clients our little Sequence abstraction, I mean, if the language already has a Range abstraction why are we defining another one?, what we really want is a way of iterating a Scala Range in steps other than 1, and I wouldn't be writing this if Scala gets in the way of our goual :-). Heres how you do it:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class MyRange(range: Range) {&lt;br /&gt;  def stepBy(step: Int) = new Iterator[Int] {&lt;br /&gt;    var x = range.start&lt;br /&gt;    &lt;br /&gt;    def hasNext = range contains x    &lt;br /&gt;    def next = { &lt;br /&gt;      val rtn = x&lt;br /&gt;      x += step&lt;br /&gt;      rtn&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;implicit def toRange(range: Range) = new MyRange(range)     // define the implicit conversion method&lt;br /&gt;&lt;br /&gt;(0 to 10).stepBy(2) foreach print      // prints "0246810"&lt;br /&gt;(0 until 10).stepBy(2) foreach print   // prints "02468"&lt;/pre&gt;Well, as you know when scala sees an instruction like (1 to 10).stepBy(2) she knows that Range doesn't have a method defined as stepBy(n: Int) so she looks in the current scope for an implicit conversion of a Range object to any other object that has that method, in this example everything works as expected, of course, old little Range gets converted to our new and shiny MyRange. The important concept to take home here is how we've been able to simplify our API. Everyone knows ranges and uses the Range object everytime they need it, we have given them others way of using the same thing that they've been using, so, everyone is happy. Really guys (ok, I know that no one really reads this, but anyway I'll say it again) it is important to stay away from complexity, very important actually, so, if there are concepts already defined that people use and love you must make use of them and add to them instead of creating new abstractions that supposedly everyone in the project must understand, and here (it is just one use case, there are many more) is when implicits shine. As you can see from our example, we let everyone use the abstraction they already know, but add to it just to make their lives simpler, that's how cool we are.&lt;br /&gt;&lt;br /&gt;BTW, in Scala the class Range has a method defined as by(step: Int): Range that serves the same purpose as our own defined method, actually that is why I have to call our stepping function in MyRange as stepBy, so basically we didn't do anything of value after all, this stepBy method is convenient but unnecessary. Anyway I presume that you get my drift.&lt;br /&gt;&lt;br /&gt;until next blather...&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-7315665354848792513?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/7315665354848792513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-more-about-implicits.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/7315665354848792513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/7315665354848792513'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-more-about-implicits.html' title='Introducing Scala - More about implicits'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-7395360336136771794</id><published>2010-05-25T10:46:00.000-07:00</published><updated>2012-01-19T12:09:54.239-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>Humor me at work</title><content type='html'>This is some interesting piece of code I've found at work, not sure who write it but it certainly can make our afternoon.&lt;br /&gt;&lt;pre class="prettyprint"&gt;function TfrmMain.IsAButtonAction(Action: TBasicAction): Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := True;&lt;br /&gt;end;&lt;/pre&gt;Very interesting function he, will I have the boldness to hit delete?&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-7395360336136771794?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/7395360336136771794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/humor-me-at-work.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/7395360336136771794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/7395360336136771794'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/humor-me-at-work.html' title='Humor me at work'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-6793122453907797229</id><published>2010-05-24T11:10:00.000-07:00</published><updated>2010-07-06T12:09:06.597-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='others'/><title type='text'>Interlude</title><content type='html'>Today is my birthday and so far I've been just coding Object Pascal at work. I've decided that life is too short to write it in Object Pascal, I rather write it in Scala or Ruby..., not really, it's worth living it and well, as Tom Waits says,  I Can't Wait to Get Off Work (And See My Baby on Montgomery Avenue)&lt;br /&gt;&lt;br /&gt;Good Luck to you all and until next blather...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-6793122453907797229?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/6793122453907797229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/today-is-my-birthday-and-so-far-ive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/6793122453907797229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/6793122453907797229'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/today-is-my-birthday-and-so-far-ive.html' title='Interlude'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-490165602882432957</id><published>2010-05-21T08:28:00.000-07:00</published><updated>2012-01-19T12:11:56.262-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Introducing Scala - Implicit Conversion</title><content type='html'>It's been a long week so far, on monday my boss give me the task of reimplementing the configurations module of our project, so I set foot in the trenches and start working. The thing is that our suit is very large and is Object Pascal, I know, I must be one of the very few people that still works in that. The problem with the configurations is that now one of our clients wanted personalized configurations, that is, they wanted for every user to have they own configurations, something like a personalized workspace. Well I will not bore you with this, so let's get to the point of it all. When I start reading the "old" configurations implementation two things where immediately obvious, first, what a mess of code!! yeah, you got that right, actually I don't like to rant against my company, at least they were kind enough to give me a job, but, and I'm trying to help here, they has a very very big technical debt to pay and they keep rising that debt, but still, the other thing was that somehow I will have to make use of the old thing, not just for that adagio of reuse and don't reimplement the wheel, but because the alternative was to write a lot of boring code to talk with oracle and made sure that everything compiles (sorry, we don't test that much either). Anyway, eventually I came with an adapter, or a set of adapters, which leads me to a facade (and it all started looking too enterprisy for my taste :-)), but since I've been looking at Scala lately I wish Object Pascal would have Implicit Conversions cause you know &lt;a href="http://jc-blatherings.blogspot.com/2010/04/oh-my-gosh-do-i-missing-design-pattern.html"&gt;how I feel about Dessign Patterns&lt;/a&gt; (the implementation in Object Pascal is not just boring and repetitive, but ugly and cumbersome, at least for someone like me that is not Pascal inclined, I will never be, actually). So, today we'll take a look at implicits in Scala, or, as I like to said when I'm in pragmatic mode, write your functions at the rigth (ok, if you're not mathematically inclined you're probably not getting the joke, but that's ok, I'm not mathematically inclined either), in pragmatic mode I said, yeah, let's take a look at how Scala solves a real problem that pops again and again in a programmer's life.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;When using libraries written by others, usually you have to take them as they are, you can't just change something because you don't have the source code or because a million other reasons, but really, how many times you've felt that some library you are using is missing something?. To alleviate this problem some languages give options to the programmer. Ruby has open classes and C# has static extension methods. Ruby as always is very permissive (methods added to a class or module are in the global scope, some may call it power, I disagree, of course, it's just anarchy and not very scalable because you never know for sure what methods a class have) and C#, not as always of course, is way behind (they solution is more local but it doesn't let you add state, just a method that is compiled as a static method). Java has, well, Scala, which answer to the problem is implicit conversions and parameters. In this installment we'll look at this feature in some detail. Let's start with a simple example to se how it all works.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  for(i &amp;lt;- 1 to 10) println(i)  &lt;/pre&gt;A simple for comprehension that loops from 1 to 10 (included) and prints every number in the sequence. I will not be explaining for comprehensions in this post, so, the importan part to look at is that '1 to 10' part. Really, for a beginner it would seem that 'to' is some language construct but it's not, it's just a method in class RichInt. Before explaining this let's take a digrassion to a little syntactic sugar that Scala let us do. When a method expects just one parameter Scala let's us ommit the dot call, this is called operator notation if I recall well, so, in the previous example we have '1 to 10' wich is another way of writing '1.to(10)' and the later form is what the compiler sees anyway, all in all, those little features are what makes a programming language great :).&lt;br /&gt;&lt;br /&gt;But wait, you know that '1' in code is literal for Int and you already seen the java doc for Int and if the compiler converts that to a method call called 'to' you know that there is no such method in Int called 'to', so, up to that you'll be right but the Scala compiler is smarter than you (aja, me too) and it don't stops there. Knowing that Int don't support a 'to' method scalac looks in the CURRENT SCOPE for an implicit conversion of Int to another object that has a 'to' method and if it finds one it happily converts and if everything types check, well, you got what you expect. In this case there is an implicit, defined in Predef wich Scala imports and is available for every Scala program (actually you must take a look at Predef to see what is there, you'll learn much of it), the definition is this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  implicit def intWrapper(x: Int) = new runtime.RichInt(x)&lt;/pre&gt;Well, as you can see is a normal method, with the implicit keyword appended (this is important, not any method will do, it has to be and implicit method), the method takes an Int as parameter (this is the object you're converting, of course) and return some other object, in this case runtime.RichInt, wich if you look in the java doc have the 'to' method, so, after the conversion of '1' to 'RichInt' the expression types check and everything works as expected. I tried to explain this in very simple terms and small steps and actually there is not much more to it (well, some rules you must be aware of, of course, but very simple ones and those you can find somewhere else, the most important thing is that the implicit method has to be in scope for the compiler to take a look at it, yeah, you must import it before use, this is actually good, is local and you extend something in a given context, other code don't have to even consider your extensions) so now you know all there is to know about implicits, yeah, you've got implicits on steroids, so, let's move to another example.&lt;br /&gt;&lt;br /&gt;I was going to make up a case of configurations, but I think I'm so tired of them already that we'll look at something different and more basic. Remember my &lt;a href="http://jc-blatherings.blogspot.com/2010/05/introducing-scala-calculating.html"&gt;last post&lt;/a&gt; about factorials, well, if you're as purist as I'm sometimes are, you would like to make a call like 5! to get the factorial of 5, it happens that you can, implicits at the rescue. &lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;class Factorial(number: Int) {&lt;br /&gt; def ! = {&lt;br /&gt;   def factorial(n: BigInt, acc: BigInt): BigInt = {&lt;br /&gt;     if(n == 0) acc else factorial(n - 1, n * acc)&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   factorial(number, 1)&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;object Factorial {&lt;br /&gt; implicit def intToFactorial(n: Int) = new Factorial(n)&lt;br /&gt;}&lt;/pre&gt;As you can see, I've created a new class called Factorial and in it declared a method called '!'. In the last post I have to pass to the method called factorial a number as parameter to calculate the factorial of, but now we'll pass that to the constructor of the Factorial class instead and with the magic of implicits (really, no magic at all, everything is very clear, really, no pun intended) we'll be able to call '!' on any number. Oh, I've created an object too, this is called a companion object which is the one that holds the implicit conversion method, so, in client code we can now do something like this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;  5! // 120&lt;/pre&gt;And how cool is that he, you can do a lot with this construction. I'll put another example, this time by the very creator of Scala, Dr. Martin Odersky:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;// define the RichArray class that will convert plain arrays to Rich one&lt;br /&gt;class RichArray[T](value: Array[T]) {&lt;br /&gt; def append(other: Array[T]): Array[T] = {&lt;br /&gt;   val result = new Array[T](value.length + other.length)&lt;br /&gt;   Array.copy(value, 0, result, 0, value.length)&lt;br /&gt;   Array.copy(other, 0, result, value.length, other.length)&lt;br /&gt;   result&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// and add an implicit conversion from plain to rich arrays:&lt;br /&gt;implicit def enrichArray[T](xs: Array[T]) = new RichArray[T]&lt;br /&gt;&lt;br /&gt;// in client code you can now write:&lt;br /&gt;&lt;br /&gt;val x = Array(1, 2, 3)&lt;br /&gt;val y = Array(4, 5, 6)&lt;br /&gt;val z = x append y&lt;/pre&gt;So, that's all for today folks, but before I leave you alone and let you take care of more important things in your live (you and me know how much annoying I can be right?) I'll put here some words from Dr. Odersky:&lt;br /&gt;&lt;div&gt;&lt;blockquote&gt;&lt;cite&gt;Implicits are a powerful, code-condensing feature of Scala...&lt;br /&gt;As a word of warning, implicits can make code confusing if they are used too frequently. Thus, before adding a new implicit conversion, first ask whether you can achieve a similar effect through other means, such as inheritance, mixin composition, or method overloading. If all of these fail, however, and you feel like a lot of your code is still tedious and redundant, then implicits might just be able to help you out.&lt;/cite&gt;&lt;/blockquote&gt;&lt;/div&gt;If you don't trust the man, fire up the Scala Interpreter and write this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;br /&gt;scala&amp;gt; "aaa".reverse == "aaa"&lt;br /&gt;res0: Boolean = false&lt;/pre&gt;Well, is false, but wait, 'aaa' reversed is not the same as 'aaa', sure it is, but take a look at String and RichString to see what is actually happening...&lt;br /&gt;&lt;br /&gt;Until next blather&lt;/div&gt;&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-490165602882432957?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/490165602882432957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-implicit-conversion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/490165602882432957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/490165602882432957'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-implicit-conversion.html' title='Introducing Scala - Implicit Conversion'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-4610166368562289740</id><published>2010-05-12T06:40:00.000-07:00</published><updated>2012-01-19T12:13:32.078-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Introducing Scala - Calculating Factorials</title><content type='html'>Today we'll calculate the factorial of a number in Scala, and learn one or two things in the process.&lt;br /&gt;&lt;br /&gt;Here's how you do it:&lt;br /&gt;&lt;pre class="prettyprint"&gt;def factorial(n: Int) = 1 to n reduceLeft(_ * _)&lt;br /&gt;&lt;br /&gt;factorial(5)  // 120&lt;/pre&gt;Ok, that's an abomination (almost, actually is very consice and works in a very cool way), but I have to get it out of my head before moving on. So, let's see what a factorial of a number is:&lt;br /&gt;&lt;br /&gt;Quoting wikipedia (http://en.wikipedia.org/wiki/Factorial) we got this definition:&lt;br /&gt;&lt;pre class="prettyprint"&gt;In mathematics, the factorial of a positive integer n, denoted by n!, &lt;br /&gt;is the product of all positive integers less than or equal to n. For example&lt;br /&gt;   5! = 1 X 2 X 3 X 4 X 5 = 120&lt;br /&gt;   0! is a special case that is explicitly defined to be 1.&lt;/pre&gt;The important thing to notice is that the factorial of some number n could be defined in terms of itself (or recursively for that matter) so, the factorial of a number n is 1 if n = 0 and n * factorial(n - 1) otherwise. Ok, I'm being annoying, just wanted we all be sitting on the same ground.&lt;br /&gt;&lt;br /&gt;So, let's give it a first shot. We'll define a function that calculates the factorial of some number n:&lt;br /&gt;&lt;pre class="prettyprint"&gt;def factorial(n: Int): Int =&lt;br /&gt; if(n == 0) 1 else n * factorial(n - 1)&lt;/pre&gt;Well, because a SerJ request I will explain a little more this time. Functions definitions in Scala start with def (just like ruby). Types annotations are like name:type, so, to our factorial we pass as parameter a value n of type Int and the function returns an Int (see the colon followed by Int after the function definition, yeah, that's the return value of the hole function). In this particular example the return value is needed 'cause the function is recursive, but most of the time Scala is perfectly capable of infering what the return value is. Other things are: semicolons are optional and hardly ever used, functions return the last value in their bodys so the return keybord is not needed... Ok, back to our example, the first thing to notice here is that Scala very closely resembles the recursive definition given above (it was a point to make, I know that you know what factorials are), but sure enough, with such a simple function, pretty much every language out there (maybe excluding Perl, SerJ can you give us an example?) resembles that definition. So, let's try it out:&lt;br /&gt;&lt;pre class="prettyprint"&gt;factorial(5)       // 120&lt;br /&gt;factorial(31)     // 738197504&lt;br /&gt;factorial(32)      // -2147483648&lt;br /&gt;factorial(33)     // -2147483648&lt;br /&gt;factorial(34)      // 0&lt;br /&gt;factorial(10000)   // java.lang.StackOverflowError&lt;/pre&gt;Ok, clearly our little factorial is giving us the wrong answer, and even a StackOverflowError, well, we have some work to do. First, the problem with the wrong answer is because in Scala, as in Java, Integers have a certain size, and we overflow that size, so, we have to use a BigInt instead. The problem with the StackOverflow is that being our factorial a recursive function it just overflow the stack, you know what the stack is rigth, well, everytime factorial calls itself it puts another frame in the stack and eventually java gets out of memory and can handle it anymore, that we will fix we something called tail recursion. But one step at a time, or iteration if you will :).&lt;br /&gt;&lt;pre class="prettyprint"&gt;def factorial(n: BigInt): BigInt =&lt;br /&gt; if(n == 0) 1 else n * factorial(n - 1)&lt;br /&gt;&lt;br /&gt;factorial(5)       // 120&lt;br /&gt;factorial(31)     // good answer, i wil not copy that...&lt;br /&gt;factorial(32)      // good answer, i wil not copy that...&lt;br /&gt;factorial(33)     // good answer, i wil not copy that...&lt;br /&gt;factorial(34)      // good answer, i wil not copy that...&lt;br /&gt;factorial(10000)   // java.lang.StackOverflowError&lt;/pre&gt;So, we have solved the first problem, and with a clean sintax too, I mean, I only append Big to any Int in the original source and it worked, how cool is that?. Let's see at the same solution in java and you'll know what i mean.&lt;br /&gt;&lt;pre class="prettyprint"&gt;public static BigInteger factorial(int n) {&lt;br /&gt; if(n == 1) {&lt;br /&gt;   return BigInteger.ONE;&lt;br /&gt; } else {&lt;br /&gt;   BigInteger fac = new BigInteger(BigInteger.valueOf(n));&lt;br /&gt;   return (fac.multiply(factorial(n - 1)));&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;Yeah well, I will not even try to cast a comment at that, it is just ugly... so, let's move on. The really cool thing here is that Scala uses the same implementation of BigInteger that java does (well not exactly so, Scala has the BigInt type, but is implemented in terms of the BigInteger java type), it works by implicit conversions, something that will be another post, sorry :(.&lt;br /&gt;&lt;br /&gt;The StackOverflow problem, as i said before, we can solve by turning the function into a tail recursive function. This is one in which the last executed statement in the function (or procedure if you are CS inclined) is to itself. The good news about Tail Recursion is that some compilers (scalac included, of course) recognise this and employ tricks so that the recursion is eliminated completely. In terms of stacks, the current stack frame being used for the caller is replaced with that of the callee, thus reusing a stack frame, instead of creating a new one. Without tail recursion the function will look something like this:&lt;br /&gt;&lt;pre class="prettyprint"&gt;factorial(5)&lt;br /&gt;5*(factorial(4))&lt;br /&gt;5*(4*(factorial(3)))&lt;br /&gt;5*(4*(3*(factorial(2))))&lt;br /&gt;5*(4*(3*(2*(factorial(1))))))&lt;/pre&gt;See?, after doing the recursive call, a multiplication is done, so, this is not tail recursion, in wich the recursive call have to be the very last call. So the system effectively creates a new stack frame every time the function calls itself. With tail recursion, we hope, things will look something like this (I could be wrong here):&lt;br /&gt;&lt;pre class="prettyprint"&gt;factorial(5,1)&lt;br /&gt;factorial(4,5)&lt;br /&gt;factorial(3,20)&lt;br /&gt;factorial(2,60)&lt;br /&gt;factorial(1,120)&lt;/pre&gt;Yeah, the current stack frame is reused, so we don't have to worry for a StackOverflow any more 'cause we use the same stack frame every time, yes, you hear well, the tail optimization that scalac is capable of doing take constant space, even if the original function is recursive. Now I know that this is old news for the Lisp community (and the functional community in general) but for me is very new and so cool...&lt;br /&gt;&lt;br /&gt;Enough blather, let's see how we implement our factorial function with tail recursion. Here I'll use a feature of scala that let me nest functions (like when you create an inner class in java but at the function level). The implementation is going to be a little more complicated that our original but, really, this is standard CS stuff and you can find papers all over the place (google I mean) about that. The important thing to get home here is that you start with your beautiful recursive implementation and later on implement a tail recursive analogous, just when the StackOverflow problem becomes a problem (you know, it's not a problem until it actually becomes a problem :), most of the time this kind of optimizations aren't really nedded). Sure enough, not every recursive function can be converted to a tail recursive one, but is good to have this feature anyway.&lt;br /&gt;&lt;pre class="prettyprint"&gt;def factorial(n: BigInt) = {&lt;br /&gt; def factorial(n: BigInt, acc: BigInt): BigInt = {&lt;br /&gt;   if(n == 0) acc else factorial(n - 1, n * acc)&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; factorial(n, 1)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;factorial(5)       // 120&lt;br /&gt;factorial(31)     // good answer, i wil not copy that...&lt;br /&gt;factorial(32)      // good answer, i wil not copy that...&lt;br /&gt;factorial(33)     // good answer, i wil not copy that...&lt;br /&gt;factorial(34)      // good answer, i wil not copy that...&lt;br /&gt;factorial(10000)   // good answer, i wil not copy that...&lt;/pre&gt;Well, it worked, no more StackOverflow exceptions creeping around. So, basically to convert our little factorial function in a tail recursive function we create a second function (nested in the original, to mantain our old api to clients untouched) with the number we are calculating the factorial of and an accumulator, then we return that accumulator if n == 0 (base case) or we call the function again decrementing n (come on, at some point we have to converge to our base case) and doing the multiplication. So, because the last statement in this new function is the call to itself it is a tail recursive call, so the compiler is capable of optimize that, which it did (scala 2.8 will have a @tailrec annotation that will inform us when the compiler is not capable of optimizing a tail recursive function). Finally, in our original function we delegate to our new one with n and an accumulator of 1.&lt;br /&gt;&lt;br /&gt;Until next blather...&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-4610166368562289740?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/4610166368562289740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-calculating.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/4610166368562289740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/4610166368562289740'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-calculating.html' title='Introducing Scala - Calculating Factorials'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-1497477159129799078</id><published>2010-05-05T05:59:00.000-07:00</published><updated>2012-01-19T12:14:30.338-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Introducing Scala - Duck Typing</title><content type='html'>&lt;div style="text-align: justify;"&gt;In this blather I wil talk about Scala, the new kid in the block. I was thinking about introducing Scala from the beginning for all the people (SerJ only) that read this, but there are so many sites that already do that see &lt;a href="http://www.artima.com/scalazine/articles/steps.html"&gt;this&lt;/a&gt;, &lt;a href="http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-1"&gt;this&lt;/a&gt; and &lt;a href="http://www.ibm.com/developerworks/java/library/j-scala01228.html"&gt;this&lt;/a&gt; that I've decided to share only my thougths without much of an explanation. Really, in the last few days I've been looking at Scala and I must say it, love everything I've seen so far. Scala is the language that the Java comunity has been waiting for, and finally we got a compiled language that blends functional and OOP and at the same time it's very pragmatic. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;In the dynamic typing community, "Duck Typing" means "if it quacks like a duck, it is a duck". So, when strongly typed languages force its typing everywhere, even when it is not needed, in a dynamically typed language if a variable quacks like a duck it is one assuming you want her to quack, meaning that this languages don't care about the type of variables, but about the things you can do with them. This is more a matter of attitude than a technical requirement, and ocasionally is a very cool feature to have. Let's look at an example in Ruby of duck typing.&lt;/div&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;class Duck&lt;br /&gt; def quack&lt;br /&gt;   'Quack!'&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def swim&lt;br /&gt;   'Paddle paddle paddle...'&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Goose&lt;br /&gt; def honk&lt;br /&gt;   'Honk!'&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def swim&lt;br /&gt;   'Splash splash splash...'&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class DuckRecording&lt;br /&gt; def quack&lt;br /&gt;   play&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def play&lt;br /&gt;   'Quack!'&lt;br /&gt; end&lt;br /&gt;end&lt;/pre&gt;Since Ruby uses duck typing, you can get a recording to quack or a goose to swim:&lt;br /&gt;&lt;pre class="prettyprint"&gt;def make_it_quack(duck)&lt;br /&gt; duck.quack&lt;br /&gt;end&lt;br /&gt;make_it_quack(Duck.new)           # =&amp;gt; "Quack!"&lt;br /&gt;make_it_quack(DuckRecording.new)  # =&amp;gt; "Quack!"&lt;br /&gt;&lt;br /&gt;def make_it_swim(duck)&lt;br /&gt; duck.swim&lt;br /&gt;end&lt;br /&gt;make_it_swim(Duck.new)     # =&amp;gt; "Paddle paddle paddle..."&lt;br /&gt;make_it_swim(Goose.new)    # =&amp;gt; "Splash splash splash..."&lt;/pre&gt;But you can't make a recording swim or a goose quack:&lt;br /&gt;&lt;pre class="prettyprint"&gt;make_it_quack(Goose.new)        # Runtime Error&lt;br /&gt;make_it_swim(DuckRecording.new) # Runtime Error&lt;/pre&gt;In java, a strongly typed language, to make a recording to quack both Duck and DuckRecording must implement the same interface, at the same time to make a goose swing both Duck and Goose must implement the same interface, leading that explosion of interfaces to a more dificult design (imaging more use cases...) and all the problems with interfaces (published interfaces are like the truth carved in stone, they stay forever and then when we want other things we have to hack in), enter scala to the rescue.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In scala you can do something similar:&lt;/div&gt;&lt;pre class="prettyprint"&gt;class Duck {&lt;br /&gt; def quack() = "Quack!"&lt;br /&gt; def swim() = "Paddle paddle paddle..."&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Goose {&lt;br /&gt; def honk() = "Honk!"&lt;br /&gt; def swim() = "Splash splash splash..."&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class DuckRecording {&lt;br /&gt; def quack() = play&lt;br /&gt; def play() = "Quack!"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;def makeItQuack(quackable: { def quack(): String }) = quackable.quack&lt;br /&gt;makeItQuack(new Duck)          // =&amp;gt; "Quack!"&lt;br /&gt;makeItQuack(new DuckRecording) // =&amp;gt; "Quack!"&lt;br /&gt;&lt;br /&gt;def makeItSwim(swimmable: { def swim(): String }) = swimmable.swim&lt;br /&gt;makeItSwim(new Duck)  // =&amp;gt; "Paddle paddle paddle..."&lt;br /&gt;makeItSwim(new Goose) // =&amp;gt; "Splash splash splash..."&lt;br /&gt;&lt;br /&gt;makeItQuack(new Goose)        // Compiler Error (Goose does not have a quack() method)&lt;br /&gt;makeItSwim(new DuckRecording) // Compiler Error (DuckRecording does not have a swim() method)&lt;/pre&gt;Well, as I said before I will not explain every detail of Scala, methods start with def, etc, etc. The thing at hand is that Scala let us treat classes (or objects for that matter) that do not share the same hierarchy in a uniformly way. The method makeItQuack, for example, expects any object that has a method with the signature "def quack(): String" (yes Scala resembles Pascal syntax when it comes to type annotations, that is in Scala you do "variable: Type" instead "Type: variable") meaning that this object must have a method called quack with no parameters and returning a String, so, every object that fulfills that contract can be passed, as the example shows, into makeItQuack, effectively doing "Duck typing". The Scala way is much more safe because if you attemp to pass some method that do not fulfill the expectations then you get a compile time error, in the ruby version you only get a runtime error.&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;That's all for today, but before leaving I want to make another point here. Duck Typing is great, when I start working with Ruby I was so amazed by the control the programmer has in such a dynamically typed language that I hardly could go back to java or c++ (or, god save me, assembler), it is great, no questions about it, and you really become a much more productive programmer enjoying more your work as a bonus. Then I took a new job working as a developer for a company that has a big software infrastructure for hotels and the like and so far I've been working in legacy code. Could talk a lot about my experiences here, but what I want to say now is that I would have a really hard time trying to fix something in such a big project if it where written in a dynamically typed language, sure, good tests helps a lot, but here we don't have any (I'm trying to convert people, no luck so far), yet, even with tests in place I think it would be almost imposible to get in and do your thing. So, it's great that Scala brings Duck Typing to the statically typed community, and it's greatest that Scala is beging explicit about it (in ruby you get the feature by default), meaning that the programmer explicity delcares the behavior he or she is expecting, but, even so, use it with care... Come on people, we need robust software, so, use types whenever you can.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Until next blather...&lt;/div&gt;&lt;/div&gt;&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-1497477159129799078?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/1497477159129799078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-duck-typing.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1497477159129799078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/1497477159129799078'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/05/introducing-scala-duck-typing.html' title='Introducing Scala - Duck Typing'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-3419290622707457504</id><published>2010-04-16T07:08:00.000-07:00</published><updated>2010-07-06T12:08:48.255-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Owning a mess or how to leave a better world for our childrens</title><content type='html'>Imaging you're the greatest chef in town, one day you're sitting in your house drinking cold beer and watching a tv program about cooking a turkey when your phone rings, in a bad mood you respond and in the other end of the line there's a freaky voice offering you a job. The thing at hand is that you must prepare a meal for a thousand people by tomorrow afternoon. After asking for a tremendous wage you accept and the phone voice give you the direction where you will find all the ingredients and utensils and she said that you can begin rigth away. Ok, as the great chef that you are, you finish your beer but knowing that a thousand people are a lot of people you leave to the given address and when you get there, well, it is a mess. Sure, you find all you need, even a crew that will work for you for the upcoming 12 hours, but your kitchen is such a mess than you can't even find a spoon. What to do?, How on earth you'll prepare a meal for a thousand commensals in that caos?&lt;br /&gt;&lt;br /&gt;Let's stay a little longer with our chef. There are a lot of actions he can do but I want to explore one with a happy ending because analogies are good and fun, but not necessarily accurate. Ok, uppon arrival you, as our starring chef, organize your crew, puts everyone to work, something like this: "Ok people, we got 12 hours to make a meal for a thousand people, this is the menu we will be serving, I want everyone working in pairs, you two, start chopping potatoes, etc, etc", and you, of course, will prepare the sauce, because everyone knows the sauce is the really hard part of any feast. So, each person gets to work and 12 hours later all the invited people has a meal to eat, everyone is happy, you collect your wage, shake everyone hands and go home to finish in the dvd that program you where watching earlier.&lt;br /&gt;&lt;br /&gt;Happy ending eh, yes, we all like that. Our chef had a decision to make, and he chose being aware of the time constraint, you know, if everyone works hard, not necesarily professional, but hard enough, we can make it, and who cares, when the feast is over, the cleaning crew gets here and clean the place out, because my job finish the momment i deliver the meal i was asked for. In chef's land maybe, but in software development it's a big mistake to think like that.&lt;br /&gt;&lt;br /&gt;The problem is recurring, nevertheless I will say it one more time. Every line of code that finds it's way into production stays with us forever, when we check something in our repository, our work it's just starting, so, we must do our best to check quality, good crafted code, professional code. By now it must be clear that we must always write quality code, and if it isn't clear already why are you reading this blog?, are you in the rigth profession?, come on, read again the las few sentences. No, really people, it's important to deliver quality. You know that adagio that goes, it compiles ergo it works?, hardly, really, everyone will appreciate good crafted code, that is, everyone in the team, in another team that has to work with your code and yourself too.&lt;br /&gt;&lt;br /&gt;So, here comes Bob again, you know Bob for my last post right, he's a little annoying guy who i'm very fond of, "Come on jc, you have written almost a book and haven't said nothing, can you say something interesting just for the sake of change?, or can I go now?", ok Bob, you've got a point there, i will, i'll try, to enumerate the implications of owning a mess and how to stay away from it.&lt;br /&gt;&lt;br /&gt;When you start working in a project that is just so hard to extend or maintain you are owning a mess. There's actually a name for it, it is called a "Big Ball of Mud" (see http://en.wikipedia.org/wiki/Big_ball_of_mud, actually architecture, as wikipedia put it, it's not my favorite word in software development, but you get the point right?), and it's ugly. Here's the thing, well crafted code stays well crafted, because future developers will try to mirror it and the opposite, the mess, just gets worse and worse in time, the thinking is like this, "if the autor of this code didn't care, why would I care, in the end, I get paid for delivering working software not for delivering value", and so the mess gets messy to a point that everyone start thinking about a rewrite. You must deliver value, at least because you love your code. You see, as Kent Beck use to said, i'm a lazy programmer with just good habits, so, if I structure my code well enough in the log run i will get to work less when change came, and change, in any project, will came, that's a fact of our live.&lt;br /&gt;&lt;br /&gt;So, what are the practical implications of owning a mess (I must say it, in my actual work I'm not just owning a mess, I'm owning the mother of all messes :(). Firstly, one important implication is that a lot of man power must be directed to the maintenance of the code base and keep away from adding new features to the product. That's an internal cheat, 'cause in what our clients are really interested is in new features, but in order to do that, a big squad has to be all day maintaining the code base, looking carefully for it not to break cause the slight change will fire a cascade of changes and bugs even in unrelated discrete porcions of our system, and no one, this is the real problem, ever deletes or rewrites a piece of that mess, as I said, if it gets into production it stays with us forever (at least in my company, if it works why would you change it..., well I can find a thousand reasons to change it). Other implications are, for example, when a new developer enters the team he must spend a lot of time trying to make sense of that mess and almost for sure he will never make complete sense of all of it, so when he start working for real he would very likely be breaking someting else. On the other hand, it's just so damn hard to add something in!!!, it too it's fragile code, rigid code, unreusable code, it is even not fun at all to work with it.&lt;br /&gt;&lt;br /&gt;Ok, by now you're clear about the importance of writing good crafted code, in another post I will talk about style, in this one, however, I want to concentrate on staying away from the mess in a designer point of view and by having good habits, you too are a lazy programmer, right?.&lt;br /&gt;&lt;br /&gt;Unclebob has defined what he calls symptoms of a rottingn dessign, he even goes further and identify some principles to bear in mind for OOD (see http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod), do yourself a favor and go read that, later, if you feel like it come back here, but what he has to said about design is by far much more importat than this blather of today. Ok, unclebob says that a rotting design (i just love the guy, look how he use the present participle implying that the design is not just rotten but rotting as days passes by) can be identified by this symptoms: Rigidity, Fragility, Immobility and Viscosity. I will not repeat what he says here, sure enough, by now you must had read what he has to say, but when designing keep at least in mind Rigidity and Fragility, because those are the more dangerous of them all, and of course, use the principles of OOD to stay away from them. Clearly to implement a system that complies with all those principles it's imposible, you, as a developer must identify the points of extension of your product and apply the principles there, always think abstract, details not matter (for us at least, they sure matter for those CS intelectuals) and remember, these principles are not a rule, just good practices, it's like eating your brocoli, everyone knows that you need to eat your brocoli every day, but sure enough you can skip one day, going against what your mother taught you, and the earth will not eat you or anything. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;The botton line&lt;/b&gt;&lt;br /&gt;Well, blatherers, I could stay talking for weeks about this, but really, I must get to work and anyone wants to read a book about this matters, we all are pragmatics, we must be, so, what can you do to stay away from that big mess you're owning. First, in a dessign standpoint, always follow uncle bob and then try to follow this practices, in no particular order, in your everyday work, incorporate them one by one until they become second nature to you:&lt;br /&gt;&lt;br /&gt;Continuous Integration, the tests make an excellent resource, enabling you to integrate more often. You get another test working and the duplication removed, and you check in, this assure all the team is in sync all the time.&lt;br /&gt;&lt;br /&gt;Refactor mercilessly, don't be afraid, whenever you find a piece of code, for tiny that it could be, and it just don't fulfill your expectations, refactor it all the way, leaving the code base a little clean than you find it.&lt;br /&gt;&lt;br /&gt;Test mercilessly, you must test everything, that's the beauty of agile developement, testing not just give you confidence, they direct the design and keep us away of those deadlines we all fear.&lt;br /&gt;&lt;br /&gt;Delete code, this is important, if you find a piece of code that is just not pulling it's weight, maybe because of refactoring or because someone left it there, you just delete it, then run all the tests and sleep confident that night.&lt;br /&gt;&lt;br /&gt;Code Review, try to do it, it's such a mind opening practice. Do it with your friends, with your peers, whatever, if you can make it a regular practice at your work, the better it gets.&lt;br /&gt;&lt;br /&gt;Work in pairs, yo'll not get it until you do it, so, try someday and you'll know.&lt;br /&gt;&lt;br /&gt;Dry, never, not ever, repeat yourself, that's the most important practice you must follow, every piece of knowledge in a system must be expressed just once, in a well defined place.&lt;br /&gt;&lt;br /&gt;Simple Design, strive for a simple design, ok, you have read my last post, but I had to say it again.&lt;br /&gt;&lt;br /&gt;Program to an interface not an implementation, that's just another way of ralaying in abstractions, as I said before, details not matter, and as unclebob says both high level modules and low level modules must depend on abstractions.&lt;br /&gt;&lt;br /&gt;So people, try to leave a better world for your childrens, every single day there's a single action you can do to get there...&lt;br /&gt;&lt;br /&gt;Until next blather&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-3419290622707457504?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/3419290622707457504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/04/owning-mess-or-how-to-leave-better.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/3419290622707457504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/3419290622707457504'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/04/owning-mess-or-how-to-leave-better.html' title='Owning a mess or how to leave a better world for our childrens'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7500847127062768609.post-6418759320798667429</id><published>2010-04-14T09:30:00.000-07:00</published><updated>2012-01-19T12:15:07.296-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software development'/><title type='text'>Oh my gosh, am i missing a design pattern?</title><content type='html'>Well, the answer to the question that forms the title of this post is, in plain english, no. Let's make that with a capital N.&lt;br /&gt;&lt;br /&gt;Don't get me wrong, i use design patterns. In the last sentence i was about to say "i like design patterns", and that very statement is one of the many reasons that you must be carefull when incorporating a pattern in your design, because patterns are not suppose to be liked, they emerge in the rhythms of design or they don't, but you don't push them into existence, just let them flow; when they are important it's going to be like a trumpet blowing in your head, trust me, i've been there, and of course, when they are just gibberish in that beautiful design you have been working for the last couple of weeks, well, is just a buzz, you know, at least we are using the hottest design patterns, ergo we are such good designers.&lt;br /&gt;&lt;br /&gt;So, WTF is this so called jc talking about? you, as my dear reader, must be asking by now. But first, let's see a piece of code written by a programmer named Jason Tiscioni and published on SlashDot (see http://developers.slashdot.org/comments.pl?sid=33602&amp;amp;cid=3636102) that perfectly caricatured the over use of design patterns with a version of the popular "Hello World" program.&lt;br /&gt;&lt;pre class="prettyprint"&gt;interface MessageStrategy {&lt;br /&gt; public void sendMessage();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;abstract class AbstractStrategyFactory {&lt;br /&gt; public abstract MessageStrategy createStrategy(MessageBody mb);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class MessageBody {&lt;br /&gt; Object payload;&lt;br /&gt;&lt;br /&gt; public Object getPayload() { return payload; }&lt;br /&gt; public void configure(Object obj) { payload = obj; }&lt;br /&gt; public void send(MessageStrategy ms) { ms.sendMessage(); }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class DefaultFactory extends AbstractStrategyFactory {&lt;br /&gt; static DefaultFactory instance;&lt;br /&gt;&lt;br /&gt; private DefaultFactory() {}&lt;br /&gt;&lt;br /&gt; public static AbstractStrategyFactory getInstance() {&lt;br /&gt;   if (instance == null)&lt;br /&gt;      instance = new DefaultFactory();&lt;br /&gt;   return instance;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public MessageStrategy createStrategy(final MessageBody mb) {&lt;br /&gt;   return new MessageStrategy() {&lt;br /&gt;     MessageBody body = mb;&lt;br /&gt;&lt;br /&gt;     public void sendMessage() {&lt;br /&gt;       Object obj = body.getPayload();&lt;br /&gt;       System.out.println(obj);&lt;br /&gt;     }&lt;br /&gt;   };&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class HelloWorld {&lt;br /&gt; public static void main(String[] args) {&lt;br /&gt;   MessageBody mb = new MessageBody();&lt;br /&gt;   mb.configure("Hello World!");&lt;br /&gt;   AbstractStrategyFactory asf = DefaultFactory.getInstance();&lt;br /&gt;   MessageStrategy strategy = asf.createStrategy(mb);&lt;br /&gt;   mb.send(strategy);&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;In case you're asking yourself (I certainly did), this program prints the line "Hello World!" in the console when you run it. So, if you ever saw code like that, then you know the dread of design patterns, a dread that is always with us, ever since, i mean, we read the GOF book.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Let's stop the babble and start the blather.&lt;br /&gt;&lt;br /&gt;Here's the thing, design patterns leads to overengineering, when you, as a programmer, make your code more flexible or sophisticated that it is suppose to be, you overengineer it, and that's bad design. Some programmers do this because they think they know where to the program will evolve in the future, but, since i lose my big ball of predictions long ago (and if i still had it with me i'll use it to won the lotto, retire to a tropical island in the caribbean and code the hell out of myself), i can't possible foretell what will happen tomorrow, sure, i can have a rough idea, but if i'm wrong then the badly designed code stays with me for the rest of time. The problem here is not just that i'm wasting precious (ideally higly paid :)) time, but that when i overengineer some piece of code then it gets complex, and that is the real problem we face, simple code is easy to maintain and extend, but when the code gets complex it is really hard to even look at it, maxime if another team or individual inherits that piece of code, and by now we all know that we spend much more time maintaining code than actually writing it.&lt;br /&gt;&lt;br /&gt;Bob says, come on jc, are you telling everyone that they can forget all they know about design patterns and start doing "the simplest thing that can possible work"?, are you really make sense of yourself?. Well Bob, thanks for the interruption, but clearly you don't understand my point. Dessign patterns are good, they give us a common vocabulary so we can discuss things much more easily and all of that, but let's not forget that they are a solution to a recurring problem given a context, so, beware your context, is all i'm saying.&lt;br /&gt;&lt;br /&gt;We, as software developers, are suppose to be in continuous integration of new insights and knowledge in order to do a better job for our clients, so, when we first come into dessign patterns it goes like this: "Oh god, this is so good, actually I can write all my code with this, how smart are those guys", and you know, it's a good thing at first, because patterns are just a really good thing and i'm glad those GOF guys have done all the hard work, but let me make you a little history. Just a few years ago i was in college and got all this fossils giving me lectures about how you are suppose to write software (in Cuba at least is like that, you know, Cuba is known for *.* and it's bad education), of course, they didn't talk about dessign patterns or anything hot, just the old misconception of analysis -&amp;gt; design -&amp;gt; code -&amp;gt; test. The point i'm trying to make here is that, back then, software development felt so bloated, so overwhelming, sure, you even enjoy a few assigments, but when you get in the wild and start building a real world project you start pulling your hair out. Now that we have refactoring and TDD it's all again into place, everything goes smooth and easy. That's what design patterns feels, for me at least, but as i said, i'm always have refactoring for evolve a bad design into a better one, so i don't have to push a pattern into my dessign, when the moment comes, i just refactor.&lt;br /&gt;&lt;br /&gt;Remember that trumpet blow in your head, well, when you feel it, first make sure you are not getting mad, not everyone hears trumpets like that, but if it is the dessign pattern trumpet, take a momment to think if you really need that pattern rigth now and remember, you write code first for people to read (even yourself) and incidentally for a computer to understand, so, stick for a simple dessign at first, and add complexity into it just when the real need arises.&lt;br /&gt;&lt;br /&gt;Until next blather...&lt;/div&gt;&lt;script type="text/javascript" language="javascript"&gt; /*&lt;![CDATA[*/ (function() {    try {        prettyPrint();    } catch(e) {        var scriptId = 'prettyPrinter';        if (document.getElementById(scriptId) === null) {            var elem = document.createElement('SCRIPT');            elem.id = scriptId;            elem.onload = function() {                prettyPrint();            }            elem.src = "https://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js";            var theBody = document.getElementsByTagName('body')[0];            theBody.appendChild(elem);        }    }})();/*]]&gt;*/ &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7500847127062768609-6418759320798667429?l=jc-blatherings.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jc-blatherings.blogspot.com/feeds/6418759320798667429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jc-blatherings.blogspot.com/2010/04/oh-my-gosh-do-i-missing-design-pattern.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/6418759320798667429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7500847127062768609/posts/default/6418759320798667429'/><link rel='alternate' type='text/html' href='http://jc-blatherings.blogspot.com/2010/04/oh-my-gosh-do-i-missing-design-pattern.html' title='Oh my gosh, am i missing a design pattern?'/><author><name>jc</name><uri>http://www.blogger.com/profile/03873967793608377710</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://1.bp.blogspot.com/-moMVqzfW_uo/TWP650NsjzI/AAAAAAAAADg/dRBC88Ku4io/s220/thumb.png'/></author><thr:total>4</thr:total></entry></feed>
