<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>GusG.us</title>
 <link href="http://gusg.us/feed.xml" rel="self"/>
 <link href="http://gusg.us/"/>
 <updated>2010-07-26T00:45:11-05:00</updated>
 <id>http://gusg.us/</id>
 <author>
   <name>Justin Knowlden</name>
   <email>gus@gusg.us</email>
 </author>

 
 <entry>
   <title>Coincidental Collision</title>
   <link href="http://gusg.us/life/coincidental-collision.html"/>
   <updated>2010-07-26T00:00:00-05:00</updated>
   <id>http://gusg.us/life/coincidental-collision</id>
   <content type="html">&lt;p&gt;Where&amp;#8217;s my rebel? Where&amp;#8217;s my angst machine? Where&amp;#8217;s my Hunter S. Thompson? Where&amp;#8217;s my iconic ode to a generation? We&amp;#8217;re lost in a commercial hell. Any rebel bursting onto the scene is gobbled up by the do-it-their-way horde of xerox marketers. Not because the rebels want to be copied, but simply because they are. Each copy dilutes the original so much that we wouldn&amp;#8217;t know original if it stuck it&amp;#8217;s dick in our eye. Everything we know and see and believe is a copy of a copy. A watered-down solution of mixed metaphor. An interest of conflict with purposeful intent; hell-bent on mindless consumption. Buy later, pay now.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve said for a long time that Chuck Palahniuk is my generation&amp;#8217;s quintessential time capsule. With Fight Club, he captured my essence, my thoughts, my present and future desires, failures, and things to be pissed off about. He had a vision. To this day I cannot work or drink with a few friends or even strangers of roughly my age without alluding to or directly inciting a quote from Fight Club. In open discussion one might hear &amp;#8220;The first rule of &lt;span&gt;such&lt;/span&gt; and &lt;span&gt;such&lt;/span&gt; is &amp;#8230;&amp;#8221;. To wit, when asked to detail my favorite movies I always say &amp;#8220;My first and second favorite movies are Fight Club&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Beyond the obvious, Chuck P. so brilliantly illustrated Generation X&amp;#8217;s obsession with consumables, our inability to truly fend for ourselves, and our inert desire to change a disgusting system we have umbilically linked ourselves to. In doing so, he captured the essence of punk and anti-establishment.&lt;/p&gt;

&lt;p&gt;But, he is no Hunter.&lt;/p&gt;

&lt;p&gt;I also believe Christopher Hitchens is a much needed force in our time. A contrarian to the Nth degree and one of the - if not the - smartest people I can think of. A discussion of thoughts through spoken word is not something you ought embark upon lightly with Hitchens; even if you think you agree with him. You will no sooner have thought what you believe to be your enlightened turd then he will have dissected it and fed it back to you.&lt;/p&gt;

&lt;p&gt;But, he too is no Hunter.&lt;/p&gt;

&lt;p&gt;Any why not? Why are they not Dr. Gonzo? They are not Hunter, because they are copiable. They are copiable not simply because they allow themselves to be copied, but because the &amp;#8220;system&amp;#8221; has recognized that people resonate with their rhetoric and find mimes to imitate their message.&lt;/p&gt;

&lt;p&gt;In the present - or not so distant one - you have Hitchens and then you a marketing team who so ilwittedly devised the &amp;#8220;Gang of Four&amp;#8221;. Hitchens, Dennet, Dawkins, and some other guy who&amp;#8217;s so sweet, nice, and likable you want to stop listening. The entire point being that they sit upon their atheistic perch and spout poetic about how great their theological position is and how not-so-great the belivers&amp;#8217; position is.&lt;/p&gt;

&lt;p&gt;Yes, you&amp;#8217;re smart. Nice fucking cardigans. Who gives a shit?&lt;/p&gt;

&lt;p&gt;As if we need a movement of atheism. Hearing smart mother fuckers referring to themselves as &amp;#8220;the brights&amp;#8221; or members of the &amp;#8220;Gang of Four&amp;#8221; is fucking embarrassing. I blush with shame to know it exists and to think they are the closest in like-mindedness to myself. I am not so smart as they, yet I know ridiculous when I see it. Hicthens himself has no qualms about asking his plethora of interview hosts ranging from contemptible to respectable to mention his book(s); &amp;#8220;In fine book stores everywhere&amp;#8221; as he is fond of pointing out. He doesn&amp;#8217;t have a problem with the capitalism of his thoughts; I have no problem with him not having these qualms, but it leaves an indelible lack of defensibility on my part and on his - yet I will not be debating him on this point &amp;#8230; ever. I like him because he has a deep insight and intellect; I can&amp;#8217;t quite completely get behind him because he seems to be missing the point.&lt;/p&gt;

&lt;p&gt;More to my point, you have copy-cats. Intellectual masturbation on worldwide scale through distribution channels such as YouTube and &amp;#8230; and &amp;#8230; well, YouTube; seems to be enough. Copy-cats come in all forms, but they seem to be less smart or perhaps more poignant and focused, but certainly less well versed. Hitchens does routinely debate or engage in discussions with these bafoons; but all-in-all, his points get lost amidst a see of contractual idiots and Hitchens seems content with merely putting up a wall to hold them back. The fame is far too strong an allure for him.&lt;/p&gt;

&lt;p&gt;Now take Chuck P. He has had a successful career. Yet since his generationally defining success with Fight Club, you apparently get his publisher asking for more which does in turn give us diluted Chuck; Choke, Pygmy, Rant, some wandering perversions into grotesque, shock fiction. He is very good at identifying a topic to dive into and then immersing himself so completely as to make himself a visual artisan with mere words as his brush. Since Flight Club, though, his topics have lost external meaning. Perhaps they mean something to Chuck and perhaps that means something to Chuck and perhaps Fight Club was a coincidental collision of Chuck&amp;#8217;s interests and generational angst - which all being true would make me even more morose.&lt;/p&gt;

&lt;p&gt;No, I believe Chuck knew he had a point just as Hitchens absolutely knows he has a point, but the two have lost themselves in a world of Disney-land ball sucking and can no longer tell when they are being mocked and when they should be offended and when they should remove the vacuum from their genitals. This is where they differed from Hunter. Not to say Hunter did not get caught up in his own fame, but it was obvious he knew when it was happening. It was also obvious he did not necessarily seek it. It was also obvious he knew he should take a side and push forward by all means necessary. He apologized not.&lt;/p&gt;

&lt;p&gt;To this point, I would agree that Hitchens is Hunter&amp;#8217;s closest contemporary. They apologize not. They do choose sides. Where they differ is in their infantileness, as Gary Hart so put it. Hunter was infantile in so much that he wanted the good to win and thought evil should suffer to no end. This is not so different from a Chuck P. finale, but is so different from a gentlemanly Hitchens.&lt;/p&gt;

&lt;p&gt;In closing, what I really want is an infantile asshole who won&amp;#8217;t take no for answer, but knows a good thing when they see it. And then I want them to write about it, tell me why I&amp;#8217;m an idiot for thinking otherwise, and have fun doing it. A life should be lived, apologies should be saved.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Pit</title>
   <link href="http://gusg.us/life/the-pit.html"/>
   <updated>2010-07-05T00:00:00-05:00</updated>
   <id>http://gusg.us/life/the-pit</id>
   <content type="html">&lt;p&gt;Sigh.&lt;/p&gt;

&lt;p&gt;Another day with no end. Another day of mindlessness. Another day of droning, comparing myself to the outward reality of others, feeling inadequate. Tomorrow will be yesterday and it is all today. It is always the present.&lt;/p&gt;

&lt;p&gt;The uneasy pit in my stomach grows larger with each passing month. Sometimes I can ignore it for a month by inventing a distraction. Something that I can become totally engrossed in and convince myself that this very thing is now the new me. This is the thing that will change my life. It will course-correct me into the path of success. Who knows, perhaps even prosperity. I am not so naive as to believe it will make me happy tomorrow, but it will certainly lead me to happiness soon. Once the world feasts their eyes on my new creation, they will love me. I will be loved.&lt;/p&gt;

&lt;p&gt;But it doesn&amp;#8217;t last. The self-imposed challenge completed, I am bored. I am bored and feeling more stupid and helpless than I did before my maniacal ego binge. No one loves me who didn&amp;#8217;t already before. The pit is still there. It makes me tense. No, I become tense because it is there. Extremely anxious. Ready to blow. It is there and is gnawing on me. Gnawm gnawm gnawm.&lt;/p&gt;

&lt;p&gt;I wish I could rip this pit out of me. If I could, I&amp;#8217;m certain it would be a cantaloupe-sized, polished ball of sheer black granite. A dense mass of impenetrable matter of whose composition is unclear and whose purpose is unknown. A house of leaves. I would see my reflection. Doubtless I would see anything else.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;On days when I&amp;#8217;m capable of doing so, I look around and I see two types of people: those that are busy and those that are in pain. I want to believe there truly are happy people out there. After all, we see them on television with their plastic smiles, spray painted body parts, hocking their brand new book, recipe, attention-draining device. We see them in videos and screencasts gleefully shining their brand new turd blossom or explaining how this new technology is a game changer. They&amp;#8217;re building religions in You Tube, mind-raping me with their disgusting, one-sided conversations of daily bullshit.&lt;/p&gt;

&lt;p&gt;But they&amp;#8217;re just busy. Distracted. When I see them, they too are totally engrossed in what they&amp;#8217;re doing. Doping their pit. Disconnecting it from their nervous system by blocking its receptors with large doses of ego.&lt;/p&gt;

&lt;p&gt;And they&amp;#8217;ll be in pain soon. It&amp;#8217;s a certainty. They&amp;#8217;ll be in their car, facade removed, when the pit will wake up. &lt;em&gt;&amp;#8220;Hey!&amp;#8221;, it says. &amp;#8220;What the fuck was that? Where was I? You drug me again? Well, back to work.&amp;#8221;&lt;/em&gt; And it will reopen that portal to the underworld. The demons will be back. There will be no Virgil to guide.&lt;/p&gt;

&lt;p&gt;For those not so lost in the glamor of vanity, they have outsourced their pit to a third-party. This agent of truth tells them that they deserve their pain for the bad things they have done or will do. Repent, repent, repent &amp;#8230; leave a small donation.&lt;/p&gt;

&lt;p&gt;The Dali Llama keeps his pit distracted with spiritual hubris. His disciples distract themselves with trying to be oh so enlightened as he. The pope&amp;#8217;s pit is telling him to stop lying. He knows he&amp;#8217;s going to hell. The yogi. The master. Their herds. They&amp;#8217;re all the same. It&amp;#8217;s all the same. Be the one or waste your time trying to become it. Not doing so will awaken the pit.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll never see a happy person. Either they don&amp;#8217;t exist or they&amp;#8217;ve succeeded and have no need to talk to me about it. It&amp;#8217;s a catch 22 on a universal scale. A divine comedy.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;No, from my perspective we&amp;#8217;re all so fucking pathetic. Distracting our pit is all we want to do. It&amp;#8217;s all we can do. We all recognize this pit. We all know it&amp;#8217;s there. There are self-help books written to address it. We&amp;#8217;re told to find the color of our parachute, drop everything and become one with the universe, be a better lover, eat less, eat more, work on motorcycles, want less, give more. There are biographies, fictions, reference materials, all written by those who want to ignore their pit. There are those who read both and still won&amp;#8217;t escape.&lt;/p&gt;

&lt;p&gt;We invent empty slogans like &lt;em&gt;&amp;#8220;Happiness is something you are, not something you obtain&amp;#8221;&lt;/em&gt; to trick ourselves into thinking we know what the fuck the universe wants and how to get there. We slap them on shirts and bumper stickers. We put them in cards that we distractingly give to others knowing it won&amp;#8217;t remove their pit.&lt;/p&gt;

&lt;p&gt;We make banners with them, &lt;em&gt;&amp;#8220;Happy Birthday&amp;#8221;&lt;/em&gt; or &lt;em&gt;&amp;#8220;Welcome Home&amp;#8221;&lt;/em&gt;. We celebrate our distraction and then go back to our suffering.&lt;/p&gt;

&lt;p&gt;We are wrong. I am wrong.&lt;/p&gt;

&lt;p&gt;We talk about it. We see psychiatrists and psychologists who are trained in distraction. Agents of illusion. At times they seem to help some of us. They&amp;#8217;re really just helping those with oversized pits shrink theirs back down to socially acceptable levels of pain and suffering. Our society can only handle so much truth.&lt;/p&gt;

&lt;p&gt;We get jobs. We need them to survive, to keep our families alive. We really just need them so that we can buy more distraction until we&amp;#8217;re dead. To ease that pain we decide we want jobs that make us feel like we&amp;#8217;re doing something good. &lt;em&gt;&amp;#8220;Fuck government. Fuck advertising. I want to do something that matters!&amp;#8221;&lt;/em&gt; Again, more distraction and this is of the worst kind. Double think. Life sucks because our job sucks because our life sucked. We trick ourselves into tricking ourselves.&lt;/p&gt;

&lt;p&gt;I want to ask myself what my pit wants from me? Why is it that vapid exercises are my only outlet? Why am I left feeling hollow? When do I feel happy? When do I feel loved? But it&amp;#8217;s pointless. Those questions are hollow in that I have to ask them at all. I&amp;#8217;m grasping at straws while drowning in the whirlpool of a galactic opera.&lt;/p&gt;

&lt;p&gt;We all die. We are dead.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>American Hypocrisy</title>
   <link href="http://gusg.us/life/american-hypocrisy.html"/>
   <updated>2010-06-19T00:00:00-05:00</updated>
   <id>http://gusg.us/life/american-hypocrisy</id>
   <content type="html">&lt;p&gt;My current place of residence is a townhouse. This implies we&amp;#8217;re attached to other people but should also imply that we&amp;#8217;re surrounded by like-living individuals; as in, there are other townhouse complexes around me. The arrangement of this particular townhouse neighborhood is such that our buildings are ass-to-ass, separated by a common driveway; the same goes in the front except that we are separated by some grass and a sidewalk.&lt;/p&gt;
&lt;img src='/images/articles/life/townhome-sketch.jpg' height='447px' alt='A sketch of the townhome makeup' width='460px' /&gt;
&lt;p&gt;Something really special about this neighborhood are my immediate, but divided neighbors. I say special because they truly are a special breed of person &amp;#8230; Let&amp;#8217;s take a for instance,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;BLAH BLAH BLAH AAAAAGGGGGHHHH. I&amp;#8217;M A LITTLE KID AND I LIKE TO YELL A LOT!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or something very similar to that was being yelled by the two little child gremlins. I&amp;#8217;m pretty certain they have some sort of brain parasite that is pressing really friggin&amp;#8217; hard on the loud wrinkle of their brain. Or maybe not.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Why?&amp;#8221;&lt;/em&gt; Because this is what I heard next,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;STOP FUCKING YELLING!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Who said that?&amp;#8221;&lt;/em&gt; Dad did. Really classy, Dad.&lt;/p&gt;

&lt;p&gt;So, to stop the children from yelling he decided yelling at them was the appropriate action. A double negative; one yell negates another, thus eliminating any yell from the cosmic sound recorder &amp;#8230; with a buffered delay.&lt;/p&gt;

&lt;p&gt;But wait, what you don&amp;#8217;t know is where Dad was in relation to the kids. The kids were in their driveway just behind their house. Dad was a knight&amp;#8217;s move away in a neighbor&amp;#8217;s driveway.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;What was he doing there?&amp;#8221;&lt;/em&gt; Partying with the neighbors.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What were they doing?&lt;/em&gt; Drinking, playing bags, watching the Stanley Cup, and &amp;#8230; oh yeah &amp;#8230; yelling a whole fucking lot.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m a dad, so I&amp;#8217;ll admit a couple of things. One, kids have an innate ability to make brain piercing sounds &amp;#8230; and then laugh about it because they know it&amp;#8217;s annoying and loud, but I guess that&amp;#8217;s what&amp;#8217;s funny to them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;HA HA HA HA! I&amp;#8217;M A KID! LISTEN TO THIS REALLY FUNNY, EAR BONE CRUNCHING SOUND I CAN MAKE WITH THIS STICK AND THIS PAN AND THIS CONCRETE DRIVEWAY! WHAM WHAM WHAM! AAAAAAGGGGGGHHHHHH IT&amp;#8217;S SO FUNNY!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So if you&amp;#8217;re blood pressure is already up, then any sound might blow your top. Two, being a hypocrite is part of being human. You make mistakes and then teach your children not to be as stupid as you. But, teaching your kids not to make a mistake by showing them how bad their mistake was with their own mistake &amp;#8230; big fail. And this, in my opinion, is the American Hypocrisy.&lt;/p&gt;

&lt;p&gt;We do this everywhere. In school, in government, in religion (if you ask me, and I don&amp;#8217;t give a shit because I&amp;#8217;m a Knowldenist), in diplomacy. I don&amp;#8217;t just mean the blatant hypocrisy of building and maintaining nuclear weapons, but something more low-level than that. As a nation, we do unto others as we want to do; then we put one finger in each ear and declare &lt;em&gt;&amp;#8220;La la la la la la la la!&amp;#8221;&lt;/em&gt; And if you have the right amount of power, there&amp;#8217;s no reason you need to pull your fingers out of your ears and scrape the wax off.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Extended Tetris</title>
   <link href="http://gusg.us/life/extended-tetris.html"/>
   <updated>2010-01-14T00:00:00-06:00</updated>
   <id>http://gusg.us/life/extended-tetris</id>
   <content type="html">&lt;p&gt;&lt;a href='http://firstpersontetris.com/'&gt;First person tetris&lt;/a&gt;, what a trip (thanks &lt;a href='http://twitter.com/assaf'&gt;Assaf&lt;/a&gt;). I&amp;#8217;m glad I do not have to rotate my world around in order to put something on a shelf. Playing it got me thinking, though. The thought was, &lt;em&gt;&amp;#8220;What would the pieces look like if the individual blocks were not forced to meet along their edges?&amp;#8221;&lt;/em&gt; As in, what if the blocks could meet at their corners.&lt;/p&gt;

&lt;p&gt;Whelp, here&amp;#8217;s how. I might be missing a few, but whatever. That would be one hell of game.&lt;/p&gt;
&lt;img src='/images/articles/extended-tetris.png' alt='Extended tetris' /&gt;</content>
 </entry>
 
 <entry>
   <title>Random Thoughts, ed. 3 - Can't Spell Waterfall</title>
   <link href="http://gusg.us/code/cant-spell-waterfall.html"/>
   <updated>2010-01-10T00:00:00-06:00</updated>
   <id>http://gusg.us/code/cant-spell-waterfall</id>
   <content type="html">&lt;p&gt;Hey! Here&amp;#8217;s another in the series of random thoughts &amp;#8230;&lt;/p&gt;

&lt;p&gt;You can&amp;#8217;t spell &lt;strong&gt;&lt;a href='http://en.wikipedia.org/wiki/Waterfall_model'&gt;Waterfall&lt;/a&gt;&lt;/strong&gt; without these words :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ew&lt;/li&gt;

&lt;li&gt;fatal&lt;/li&gt;

&lt;li&gt;real flaw&lt;/li&gt;

&lt;li&gt;fear wall&lt;/li&gt;

&lt;li&gt;fear &lt;a href='http://en.wikipedia.org/wiki/Walt_Disney'&gt;Walt&lt;/a&gt; - &lt;em&gt;It&amp;#8217;s a damned mickey-mouse methodology&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;we fall&lt;/li&gt;

&lt;li&gt;all wet&lt;/li&gt;

&lt;li&gt;late war&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wiktionary.org/wiki/faal'&gt;faal&lt;/a&gt; - &lt;em&gt;Languages are tools, not boundaries&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wiktionary.org/wiki/fey'&gt;fae&lt;/a&gt; law&lt;/li&gt;

&lt;li&gt;a tall few&lt;/li&gt;

&lt;li&gt;wart ale&lt;/li&gt;

&lt;li&gt;flea trawl&lt;/li&gt;

&lt;li&gt;fat aw&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wiktionary.org/wiki/lar'&gt;Lar&lt;/a&gt; tale&lt;/li&gt;

&lt;li&gt;a lew fart&lt;/li&gt;

&lt;li&gt;wall art&lt;/li&gt;

&lt;li&gt;a flare&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wiktionary.org/wiki/rale'&gt;rale&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;later&lt;/li&gt;

&lt;li&gt;&lt;a href='http://en.wiktionary.org/wiki/lawfare'&gt;lawfare&lt;/a&gt; - &lt;em&gt;you can make it mean something&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;after wall - &lt;em&gt;it&amp;#8217;s just an anagram&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other points of note are that some of the words that can be made from &amp;#8220;waterfall&amp;#8221; relate to authority in some language or another, for instance: Lar, frea, and walt.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Narcissus</title>
   <link href="http://gusg.us/life/narcissus.html"/>
   <updated>2009-11-30T00:00:00-06:00</updated>
   <id>http://gusg.us/life/narcissus</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve been thinking this little thought for a long, long time. Probably as long as I&amp;#8217;ve known my wife. Actually, I believe it is that long, but she&amp;#8217;ll have to confirm because she has proclaimed her memory to be of mightier ilk than mine. So this thought is &lt;em&gt;&amp;#8220;Wouldn&amp;#8217;t it be fun to start a cover band who&amp;#8217;s songs are all twisted to sound narcisstic?&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The answer is, &lt;em&gt;&amp;#8220;Yes, it would be tons of fun!&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And the name of this band? &lt;strong&gt;Narcissus&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What songs would we sing? Here&amp;#8217;s a spontaneous list I&amp;#8217;ve been working on for a while:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=oiS8YokFzeY'&gt;I am the Wind Beneath Your Wings&lt;/a&gt; - &lt;em&gt;Bette Midler&lt;/em&gt; (I think)&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=pK4pl_frlPg'&gt;If You Could Build Your Whole World Around Me&lt;/a&gt; - &lt;em&gt;Marvin Gaye&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=Yrch66gdjjk'&gt;I&amp;#8217;m Even Better than the Real Thing&lt;/a&gt; - &lt;em&gt;U2&lt;/em&gt; - This reminds me of when I was 16, just got my license, it&amp;#8217;s December but really sunny and no snow, and I&amp;#8217;m driving past golden fields of unharvested corn stalks in rural Ohio. Perhaps one of my all time favorite songs. For real. I get tingles.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=iUiTQvT0W_0'&gt;Nothing Compares 2 Me&lt;/a&gt; - &lt;em&gt;Sinead O&amp;#8217;Connor&lt;/em&gt; - Love the haircut. If it wasn&amp;#8217;t for space monkeys in Fight Club, I&amp;#8217;d have to say she was my inspiration for choosing a hairstyle.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=PzYlj41YVzA'&gt;You Miss Me&lt;/a&gt; - &lt;em&gt;Björk&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=omWQzYycyJk'&gt;I&amp;#8217;m So Vain&lt;/a&gt; - &lt;em&gt;Carly Simon&lt;/em&gt; - Probably not what you expected :) BAM! It&amp;#8217;s like one of those pop-in-and-ruin-your-photo-persons but in the form of a video.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=6MMcLEdkY68'&gt;All For Me&lt;/a&gt; - &lt;em&gt;Sister Hazel&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.youtube.com/watch?v=zTneO6UgRuM'&gt;I Touch Myself&lt;/a&gt; - &lt;em&gt;The Divinyls&lt;/em&gt; - What a perfect song; no changes necessary. Well &amp;#8230; that&amp;#8217;s not true. &lt;em&gt;&amp;#8220;When I think about me I &amp;#8230;&amp;#8221;&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;8 songs should be enough for a demo I think. 8 also seems to come up a lot in my life, even though 7 is my favorite number and 12:34 shows up on the clock a lot - or I notice it a lot - and the sum of 12:34 is 1 (10 then 1 + 0).&lt;/p&gt;

&lt;p&gt;Maaaayyybe - and this is just a maybe - my lucky number is 187. Thoughts?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Changes in Riot 0.10</title>
   <link href="http://gusg.us/code/ruby/changes-in-riot-0-10-0.html"/>
   <updated>2009-11-23T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/changes-in-riot-0-10-0</id>
   <content type="html">&lt;p&gt;Though I&amp;#8217;ve never blogged about &lt;a href='http://github.com/thumblemonks/riot'&gt;Riot&lt;/a&gt;, it received some awesome and much unexpected attention from &lt;a href='http://alexyoung.org/2009/10/26/riot-testing/'&gt;Alex Young&lt;/a&gt; (a super-awesome dude), &lt;a href='http://www.rubyinside.com/riot-for-fast-expressive-and-focused-unit-tests-2669.html'&gt;Ruby Inside&lt;/a&gt; via &lt;a href='http://www.ricroberts.com/'&gt;Ric Roberts&lt;/a&gt; (another super-awesome dude), &lt;a href='http://railsenvy.com/2009/10/28/episode-098'&gt;Rails Envy&lt;/a&gt;, and &lt;a href='http://ruby5.envylabs.com/episodes/24-episode-23-october-30-2009/stories/186-riot-testing-framework'&gt;Ruby5&lt;/a&gt;. I was overcome to say the least, partly because I wasn&amp;#8217;t happy with where Riot was at that moment, but mostly because I wrote Riot for me and didn&amp;#8217;t think anyone (except for &lt;a href='http://toothrot.net/'&gt;toothrot&lt;/a&gt; and &lt;a href='http://github.com/jonpliske'&gt;jonpliske&lt;/a&gt;) would actually think Riot was for them.&lt;/p&gt;

&lt;p&gt;I was wrong.&lt;/p&gt;

&lt;p&gt;In the short period of time between then and now I have received a lot of positive feedback and only vicariously have seen some negative feedback &amp;#8230; which I will ignore because - as I said before - I wrote Riot for me. Also in that time I have received some of that famous help from the open-source community. &lt;a href='http://annealer.org'&gt;annealer&lt;/a&gt; and &lt;a href='http://github.com/brianc'&gt;brianc&lt;/a&gt; (also the lead singer of &lt;a href='http://deadblackhearts.com/'&gt;Dead Black Hearts&lt;/a&gt; - which is awesome) helped me to narrow in on what Riot was trying to accomplish and to do it with a more efficient engine. I&amp;#8217;m happy to say I&amp;#8217;m much happier with how Riot is implemented today than I was when &lt;a href='http://gemcutter.org/gems/riot/versions/0.9.12'&gt;0.9.12&lt;/a&gt; was released.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Whatever! The changes, Jabberjaw&amp;#8221;, you exclaim. Fine. In terms of DSL, there aren&amp;#8217;t many changes.&lt;/p&gt;

&lt;h4 id='assertion_macros'&gt;Assertion macros&lt;/h4&gt;

&lt;p&gt;The biggest observable change by far is in the way you write assertion macros, such as: &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;raises&lt;/code&gt;, &lt;code&gt;kind_of&lt;/code&gt;, etc. You won&amp;#8217;t need to do this very often, but when you do you won&amp;#8217;t be defining a new method that can be included into &lt;code&gt;Riot::Assertion&lt;/code&gt;. Now, you will be writing an assertion macro block. But, examples are the best way to show this. So, instead of writing the &lt;code&gt;kind_of&lt;/code&gt; macros like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;My&lt;/span&gt;
  &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;AssertionMacros&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;kind_of&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;expected&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='n'&gt;actual&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;kind_of?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;expected&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='nb'&gt;fail&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;expected kind of &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;expected&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;, not &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;actual&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;inspect&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='no'&gt;Riot&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Assertion&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;instance_eval&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;My&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;AssertionMacros&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;you&amp;#8217;re going to write them like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Riot&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Assertion&lt;/span&gt;

  &lt;span class='n'&gt;assertion&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:kind_of&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;actual&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;expected&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='n'&gt;actual&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;kind_of?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;expected&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='n'&gt;pass&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='nb'&gt;fail&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;expected kind of &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;expected&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;, not &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;actual&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;inspect&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Why? That has a lot to do with the under-the-hood changes. Important to note are a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The obvious closure&lt;/li&gt;

&lt;li&gt;The &lt;code&gt;actual&lt;/code&gt; value is getting provided-to and no longer requested-by the assertion macro&lt;/li&gt;

&lt;li&gt;The &lt;code&gt;pass&lt;/code&gt; and &lt;code&gt;fail&lt;/code&gt; signals which are required to be returned from any assertion macro&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Not listed here is an &lt;code&gt;error&lt;/code&gt; signal, but you shouldn&amp;#8217;t need to worry about that.&lt;/p&gt;

&lt;h4 id='shortcut_assertion_for_the_topic'&gt;Shortcut assertion for the topic&lt;/h4&gt;

&lt;p&gt;The assertion shortcut &lt;code&gt;topic&lt;/code&gt; has been renamed to &lt;code&gt;asserts_topic&lt;/code&gt;, which brianc so elegantly suggested as a better name. Thus, instead of this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;context&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;setup&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;mom&amp;quot;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='n'&gt;topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;kind_of&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;# This will no longer work&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;you would now do the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;context&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;setup&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;mom&amp;quot;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='n'&gt;asserts_topic&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;kind_of&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;brianc added another shortcut for doing the same thing, which also allows you to have a custom description. You could write the above example like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;context&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;setup&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;mom&amp;quot;&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='n'&gt;asserts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;the topic is&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;kind_of&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='story_output'&gt;Story output&lt;/h4&gt;

&lt;p&gt;After looking at what Alex Young &lt;a href='http://alexyoung.org/2009/11/04/riotjs/'&gt;did for output&lt;/a&gt; in his implementation of &lt;a href='http://github.com/alexyoung/riotjs'&gt;Riot for JavaScript&lt;/a&gt;, I fell in love. So, this is now the default output format for Riot and what I&amp;#8217;m calling the Story Report since the output kind of reads like a story.&lt;/p&gt;
&lt;img src='/images/articles/code/ruby/riot-0-10-1-story-terminal.png' alt='Riot terminal output, story report' /&gt;
&lt;p&gt;Who doesn&amp;#8217;t like pictures?&lt;/p&gt;

&lt;h4 id='under_the_hood'&gt;Under the hood&lt;/h4&gt;

&lt;p&gt;Oh man, everything is a little different. In essence, it&amp;#8217;s a complete re-write. This re-write was going after a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Riot needed to be faster. Twice as fast as Shoulda is not compelling.&lt;/li&gt;

&lt;li&gt;Riot should keep less state (be more functional), because state is a terrible thing to change&lt;/li&gt;

&lt;li&gt;Riot should not run the tests while also parsing the DSL (this REALLY bugged me)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In order to accomplish (1) and (3), annealer actually did some &lt;a href='http://github.com/thumblemonks/riot/blob/7cf674c257fbb2e465116ad31b7721c5cba9b23a/lib/riot/experiment.rb'&gt;crazy spiking&lt;/a&gt; on what we called the experimental approach. Essentially, anonymous classes, &lt;code&gt;define_method&lt;/code&gt;s, and meta-programming galore. And it was good.&lt;/p&gt;

&lt;p&gt;But, it did not get me (2) in a way that I thought was most readable. Experimental was a bit too magical for even me and that&amp;#8217;s probably because I&amp;#8217;m not that smart. So, we applied the learnings from experimental with an approach that never changed the state of a Context, Assertion, or Situation and we came up with the hybrid approach. I should say that Context, Assertion, and Situation have state, but the intention is for it not to change while the tests are running. Instead, state should be defined when initializing (or setting up) the respective element.&lt;/p&gt;

&lt;p&gt;All of this combined into some really readable code that is now Riot &lt;code&gt;0.10&lt;/code&gt;. There are more changes, but you should read the code to discover them. The &lt;a href='http://gist.github.com/240353'&gt;benchmarks&lt;/a&gt; are pretty awesome, too. Especially those for Ruby 1.9. If you ask me, there&amp;#8217;s no reason to use mini-test when writing new tests for 1.9. Just switch to Riot ;)&lt;/p&gt;

&lt;p&gt;As an aside, the instance that does change state over the course of running a test-suite is the test reporter. I can live with it for now, but it&amp;#8217;d be pretty awesome if the reporter could go stateless. It would also be pretty sweet if someone would run Riot contexts through one of the parallel test distributors out there. The performance gains would be outrageous. If annealer ever finishes his implementation of Jenga, I wouldn&amp;#8217;t have to ask. Ahem!&lt;/p&gt;

&lt;h2 id='riot_rails'&gt;Riot Rails&lt;/h2&gt;

&lt;p&gt;I would really like some help building out Riot to have custom support for Rails. I started &lt;a href='http://github.com/thumblemonks/riot_rails'&gt;Riot Rails&lt;/a&gt; and am slowly adding things as I&amp;#8217;m working on a custom Rails app, but the progress is slow. The progress is slow mainly because I have also side-tracked myself with learning Clojure. I want to learn Clojure because a) I like Lisp, b) I like functional languages, and c) I want to re-write &lt;a href='http://github.com/thumblemonks/evoke'&gt;Evoke&lt;/a&gt; with &lt;a href='http://github.com/weavejester/compojure'&gt;Compojure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, re-writing Evoke in Clojure is a simple enough task (except for the delayed job processing which I&amp;#8217;ll have port over), but Clojure is a JVM language. This means Compojure is dependent on Java libraries like: jetty, apache commons, clojure-contrib, etc. Being dependent on so many libraries is just begging for package management and I suppose Maven provides that, but I dislike Maven and Ant for all of their XML horrificness (I used to be a Java programmer). I just hate it. Makes me want to barf. What I do like is Ruby Gems. I really like Ruby Gems. Turns out, annealer hates Maven and likes Ruby Gems as well. So &amp;#8230; what do you think we did?&lt;/p&gt;

&lt;p&gt;&lt;a href='http://javagems.org'&gt;JavaGems&lt;/a&gt;, that&amp;#8217;s what. We up and &lt;a href='http://github.com/javagems'&gt;did it&lt;/a&gt; and there will be a LOT more to say about that. However, all of this side-trackiness has kept me from finishing Riot Rails which is not all that hard of a thing to do, it just takes time and as I have already shown I can lose that very quickly.&lt;/p&gt;

&lt;p&gt;Thusly and therefore, I&amp;#8217;m calling all arms. Let&amp;#8217;s get Riot Rails finished. It&amp;#8217;ll accomplish what I set out to do, make functional tests in Rails faster. That&amp;#8217;s right! Slowness of Shoulda + Factory Girl + functional-tests made me write Riot. That&amp;#8217;s why Riot only calls &lt;code&gt;setup&lt;/code&gt; once per Context. That&amp;#8217;s why finishing Riot Rails will make me oh so very happy.&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;d like to help, but not sure how, hop into the &lt;code&gt;#riot&lt;/code&gt; room on irc.freenode.net. Ohhhhh &amp;#8230; the riot room, that&amp;#8217;s funny. I know, it&amp;#8217;s really a channel, but whatever! If you don&amp;#8217;t want to do that, just fork and fix.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lucid Thoughts, ed. 1</title>
   <link href="http://gusg.us/life/lucid-thoughts-ed2.html"/>
   <updated>2009-11-10T00:00:00-06:00</updated>
   <id>http://gusg.us/life/lucid-thoughts-ed2</id>
   <content type="html">&lt;p&gt;&amp;#8220;Heroine&amp;#8221;, he whispers into my ear.&lt;/p&gt;

&lt;p&gt;Amidst a bustling crowd at O&amp;#8217;Hare&amp;#8217;s Terminal 3, I shudder and turn to face Fear. As suddenly I see him I grab his hand which is holding a syringe full of liquid. Fear moves away but I have it by the hand and I yank back while lifting the elbow of my free arm. Fear&amp;#8217;s eye-socket and nose crunch, or maybe snap, behind my elbow. Fear loses its footing and falls.&lt;/p&gt;

&lt;p&gt;An ocular cavity is in need of searching by the TSA.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Help&amp;#8221;, I yell. Although, I don&amp;#8217;t know why. I certainly don&amp;#8217;t need it. A man with a syringe full of something does, but I don&amp;#8217;t really care about that.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Stop!&amp;#8221;, cries a uniformed pudge-cicle from a few feet away.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Stop what?&amp;#8221;&lt;/p&gt;

&lt;p&gt;&amp;#8220;Let go of the man and put your hands above your head!&amp;#8221;, he yells as he waddles hastily towards me.&lt;/p&gt;

&lt;p&gt;&amp;#8221;I&amp;#8217;ll let go, but I&amp;#8217;m not putting my hands above my head. I&amp;#8217;ll go wherever you need me to.&amp;#8221; He&amp;#8217;s not even looking Fear in the face. He&amp;#8217;s only looking at me. I&amp;#8217;m getting nervous and possibly angry.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Hands behind your head&amp;#8221;, he says again. This time very quickly and not quite as loud. Seeing that I do not want to oblige, he gets agitated.&lt;/p&gt;

&lt;p&gt;&amp;#8221;I&amp;#8217;m not doing it!&amp;#8221;, I yell even more loudly. Now I start skipping a little and in a circle to avoid his clammy grasp, which is now also holding handcuffs. &amp;#8220;Somebody help! This guy&amp;#8217;s not a cop!&amp;#8221;&lt;/p&gt;

&lt;p&gt;For an unknown reason, he pulls a gun. I recoil and instantly grab his wrists. I can feel it bubbling inside me. A rage I have never felt. An incredible hulk of a rage. I point his gun hand towards the sky and roar at him from an entire pride of lions laying just beneath my chest. My foot lifts up and I kick as hard as I can.&lt;/p&gt;

&lt;p&gt;The cop, or fake cop, is now a screaming line-drive which has put a hole in the scoreboard; otherwise known as the bank of departure monitors. He&amp;#8217;s seemingly lifeless, I have a hand in my hand which is also holding a gun, and a one-eyed, instant-freak is bleeding behind me.&lt;/p&gt;

&lt;p&gt;I run &amp;#8230; I jump &amp;#8230; I can fly.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;If one could become or could do whatever it is they believed they could, could one believe they knew everything and if they could, what would everything be? Does knowledge defy death?&lt;/p&gt;

&lt;p&gt;If you believed yourself to be immortal, would time cease to exist? Would you suddenly exist in the past? Would you then have already existed there anyways?&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I can&amp;#8217;t sleep &amp;#8230; again.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>DailyJS.com</title>
   <link href="http://gusg.us/code/daily-js.html"/>
   <updated>2009-11-05T00:00:00-06:00</updated>
   <id>http://gusg.us/code/daily-js</id>
   <content type="html">&lt;p&gt;A few days ago &lt;a href='http://alexyoung.org/'&gt;Alex Young&lt;/a&gt; and &lt;a href='http://www.ricroberts.com/'&gt;Ric &amp;#8220;Swirrly&amp;#8221; Roberts&lt;/a&gt; started a news blog called &lt;a href='http://dailyjs.com/'&gt;Daily JS&lt;/a&gt; (aka Daily JavaScript). As you can imagine, it&amp;#8217;s news and stuff about &amp;#8230; JavaScript. Terrificly enough, they invited me to contribute (probably because I update &lt;em&gt;THIS&lt;/em&gt; blog so often ;) Anyways, I will-be/have-been contributing it and you should-be/will-be reading it. Right?&lt;/p&gt;

&lt;p&gt;We already have quite a few thoughts in the queue about interesting things we want to post about; so long as we can make it fit into 3 paragraphs; of which Alex has broken his own rules at least two times.&lt;/p&gt;

&lt;p&gt;I actually think grabbing the Daily*.com series of domains was a stroke of genius. It&amp;#8217;s so simple, yet I never even thought about it. Well &amp;#8230; now I&amp;#8217;ve thought about it and I think it would be great if someone (read: me) started a &lt;a href='http://dailyqa.com'&gt;DailyQA.com&lt;/a&gt;. I have the &lt;a href='/work/i-hired-him.html'&gt;perfect candidate&lt;/a&gt; in mind to do the contributing ;)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>I went and hired him</title>
   <link href="http://gusg.us/work/i-hired-him.html"/>
   <updated>2009-11-04T00:00:00-06:00</updated>
   <id>http://gusg.us/work/i-hired-him</id>
   <content type="html">&lt;p&gt;So, do you remember when I &lt;a href='/code/affirmation-of-a-programmer.html'&gt;talked about my friend&lt;/a&gt; &lt;a href='http://my-unemployment-challenge.blogspot.com/'&gt;Kurt&lt;/a&gt; who came in to play programmer for a day? Well, I was so impressed with his skills, I figured &amp;#8220;Why not hire him on part-time to do our QA at &lt;a href='http://carerunner.com'&gt;CareRunner&lt;/a&gt;?&amp;#8221; Because I&amp;#8217;ve never mentioned it, I&amp;#8217;m leading the technology department for CareRunner, which is a small start-up. Anyways, it&amp;#8217;s been two weeks, he has no idea what QA exactly is yet, but he&amp;#8217;s doing a great job of finding the superficial problems we developers are no good at. He&amp;#8217;s already learning how unrelated actions in performed in tandem can create unexpected results. His keen eye doubles as a typo magnet as well.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve also tasked him with understanding what QA is, learning advanced testing techniques, and how he can go about automating his job. Selenium being the first obvious choice for automation. I&amp;#8217;m really interested to see how well his music background helps in this area; specifically, that of composing a symphony of tests and suites. Finding patterns and what not. He&amp;#8217;s also pretty aggravated that he can&amp;#8217;t find any good educational material yet, which is great. Necessity is the mother of invention.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Affirmation of a programmer</title>
   <link href="http://gusg.us/code/affirmation-of-a-programmer.html"/>
   <updated>2009-10-06T00:00:00-05:00</updated>
   <id>http://gusg.us/code/affirmation-of-a-programmer</id>
   <content type="html">&lt;p&gt;Yesterday, a friend of mine came to the &lt;a href='http://github.com/thumblemonks'&gt;Thumble Monks&lt;/a&gt; office. His name is Kurt. His mission was to be a programmer for the day. This is an odd event because Kurt has no computer background. He only just recently received his BA with a major in music. So why is he coming in to play make believe programmer?&lt;/p&gt;

&lt;p&gt;Turns out, the job market sucks. And it&amp;#8217;s especially sucking for new graduates. It&amp;#8217;s an employers market at the moment. This doesn&amp;#8217;t mean Kurt suddenly wants to be a programmer. He doesn&amp;#8217;t. Instead, what Kurt is doing is &lt;a href='http://my-unemployment-challenge.blogspot.com/'&gt;trying something new every day&lt;/a&gt; in the hopes that he has fun, takes his mind of the shit, and perhaps even attracts some attention. After all, Kurt&amp;#8217;s not a dumby. He&amp;#8217;s a really smart dude. Right now, however, there&amp;#8217;s a global warming of unemployment. The ocean of employables is rising. And with so many different size fish out there, how can Kurt stand out?&lt;/p&gt;

&lt;h3 id='it_really_made_me_think'&gt;It really made me think.&lt;/h3&gt;

&lt;p&gt;The first and really only introspective thing I thunk was &lt;em&gt;&amp;#8220;why am I so fucking whiney?&amp;#8221;&lt;/em&gt; Seriously! How can I be so &lt;a href='/life/random-thoughts-ed-1.html'&gt;fucking&lt;/a&gt; &lt;a href='/life/the-path.html'&gt;whiney&lt;/a&gt;? I&amp;#8217;ve got a good job. I&amp;#8217;ve had a good job for 12+ years. I&amp;#8217;ve had a terrific boss or two for that entire time. I&amp;#8217;ve been able to work with good people. I&amp;#8217;ve been able to grow personally and professionally. I&amp;#8217;ve been able to get raises. I&amp;#8217;m able to work on my own side projects and have hobbies (which means I&amp;#8217;m pretty stable). I&amp;#8217;m now working out of my own office which is 3 miles from home for a small start-up that I&amp;#8217;ve helped get off the ground because it&amp;#8217;s what &lt;strong&gt;I&lt;/strong&gt; wanted to do.&lt;/p&gt;

&lt;p&gt;Really, why am I whining when there are lots of people like Kurt out there who want some of that, but aren&amp;#8217;t being given a chance?&lt;/p&gt;

&lt;p&gt;I don&amp;#8217;t know. But, my perspective has changed.&lt;/p&gt;

&lt;h3 id='but_i_digress'&gt;But I digress&lt;/h3&gt;

&lt;p&gt;The second thing I thunk bubbled up after Kurt left. The thing I thunk was &lt;em&gt;&amp;#8220;that was pretty impressive&amp;#8221;&lt;/em&gt;. Though Kurt &lt;a href='http://my-unemployment-challenge.blogspot.com/2009/10/speaking-in-code.html'&gt;summed up his day&lt;/a&gt; pretty well on his own, my summary of the day is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ability to ask questions&lt;/li&gt;

&lt;li&gt;ability to see the tree and the forest&lt;/li&gt;

&lt;li&gt;ability to question the status quo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not obvious things, especially for someone completely foreign to the environment and the practices. But, Kurt jumped right in by asking a boat load of questions about everything: how the company was organized, how do we run things, yada yada yada. Into the daily stand he noticed some typos on a page we had all been staring at for a day.&lt;/p&gt;

&lt;p&gt;At one point Kurt questioned - and I&amp;#8217;m paraphrasing - why we had to jump through so many hoops to program something that seems so obvious and has been done for 100s of years. The scenario being: we have a pretty long list of HTML checkboxes whose labels were sorted alphabetically (20 or so). We were distributing these across 2 columns, but were doing it left-to-right, which is a simple exercise. Instead, we were asked to display these in vertical columns distributed evenly. Not such an easy exercise. But to Kurt, it should have been. After all, we&amp;#8217;ve been doing this same thing with newspapers, books, periodicals, etc. for centuries; displaying content across multiple columns. Geez!&lt;/p&gt;

&lt;p&gt;It never really occurred to me to question this as I had already accepted the fact that code needed to be written. It impressed me that Kurt didn&amp;#8217;t hesitate to point out the ridiculousness of this fact.&lt;/p&gt;

&lt;p&gt;I have to say, though, that the thing that really struck me was that Kurt was able to help me code without having knowledge of the language itself or even how to assemble software in general. When stuck, Kurt was able to ask questions that helped to simplify or crystalize decisions for me, with phrases like: &lt;em&gt;&amp;#8220;why don&amp;#8217;t you just &amp;#8230;&amp;#8221;&lt;/em&gt; and &lt;em&gt;&amp;#8220;why do yo need to &amp;#8230;&amp;#8221;&lt;/em&gt;. This was quite an affirmation for me. While it is certainly true that Kurt is an intelligent person, it is also true that I had to explain or talk through what I was doing more. This in turn helped Kurt to ask questions and us to get to a meaningful decision efficiently.&lt;/p&gt;

&lt;p&gt;The affirmation came by way of recognizing just how effective pair programming is and why we should be doing it more often than we pretend we are. It&amp;#8217;s just sort of obvious that open dialogue is a necessity for anything. When we have open dialogue we are able to adjust our beliefs and alter our trainings. With open dialogue, everyone can be a critic and you must learn to trust. With open dialogue comes feedback from all walks of life.&lt;/p&gt;

&lt;p&gt;We should also not limit our discussions to those who are just like us. We all know this, but how often do we practice it? If you&amp;#8217;re a liberal, how often do you go to a republican and simply have an open discussion of the issues? I don&amp;#8217;t &amp;#8230; ever. I either make a joke, avoid the discussion outright (probably for lack of knowledge, but more for lack of want to appear ilinformed), or I get defensive. I could actually have an open discussion, but it has to start with me.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not really certain what any of this means. I guess it could mean that if you&amp;#8217;re at work and you can&amp;#8217;t find a programmer to pair with then grab the office manager, grab the overworked accountant, grab the HR person who&amp;#8217;s not doing anything anyways. Just grab someone and see if it makes a difference.&lt;/p&gt;

&lt;p&gt;It could also mean other things and for those, I&amp;#8217;m open to discussion.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Our Path</title>
   <link href="http://gusg.us/life/the-path.html"/>
   <updated>2009-09-22T00:00:00-05:00</updated>
   <id>http://gusg.us/life/the-path</id>
   <content type="html">&lt;p&gt;We are on a path to somewhere. This path is not a straight one. This is not a concrete path across an urban landscape. This is not the asphalt of a newly groomed forest preserve trail. This is not the path leading to grandma&amp;#8217;s back door. Where the porch door is always lighter than you expect and shuts with an antique brusqueness. Where home fried potatoes, sausage hamburgers, or anything else dreamed can be asked for and readied with excitement. Where the smell of healing salves, freshly read newspapers, and wisdom anchor themselves to every fabric in the reading room (because the TV is not for watching).&lt;/p&gt;

&lt;p&gt;Nope. This is an ancient path we&amp;#8217;re on. One troddened by the Mayans some 1200 years prior. Up mountains and over rocky terrain. Where you can&amp;#8217;t see but two feet in either direction. Great green overgrowth obtusely dissolving any trace of us having been where we stepped but 10 seconds prior. This path though rough is still a natural one. We must trust the path as the animals have to come to trust it. The duality of this path is that it both leads and masks our way. We know where we want to be, but we don&amp;#8217;t know where we&amp;#8217;re going.&lt;/p&gt;

&lt;p&gt;Trusting this path will no doubt lead us to a cliff. Upon reaching this cliff we must descend it and we will no doubt find the descent easier than imagined. But by reaching its summit we will have found ourselves at a beach with it&amp;#8217;s familiar and uplifting smells of freedom and fish. The weight of our journey will have been forgotten and only an ocean of possibility will be at our feet.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Random Thoughts, ed. 1</title>
   <link href="http://gusg.us/life/random-thoughts-ed-1.html"/>
   <updated>2009-08-04T00:00:00-05:00</updated>
   <id>http://gusg.us/life/random-thoughts-ed-1</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m not in the mood to write anything technical. I just don&amp;#8217;t want to. I don&amp;#8217;t know if I&amp;#8217;m bored, burned out, disinterested, been-there-done-that, any of the above, none of the above. Sounds like apathy. I don&amp;#8217;t think it is because I care about technical writing. I don&amp;#8217;t care for silly, self-serving blog posts about how great I think I am because I wrote a piddly little gem. I don&amp;#8217;t particularly want to sell my own brand even though the entire community of like-living individuals does that very thing.&lt;/p&gt;

&lt;p&gt;I feel annoyed, anxious, frustrated, tired, or something. I feel annoyed that I don&amp;#8217;t care about doing this. I did care about doing this. What happened? Where did it go? What is it that I really want to do? Do I want to do anything? I&amp;#8217;m not really sure where I&amp;#8217;m at. Am I just getting old? Did I already do everything I wanted to do? What color is my parachute? Why the fuck would I want to jump out of plane right now?&lt;/p&gt;

&lt;p&gt;I think I need someone to push me and someone I can push. I have challenges all around me, but I&amp;#8217;m not motivated to go get them. What the hell happened? I had a whole path laid out. I was really going to get shit done. I put the things I wanted to do on a spreadsheet. I did some of them. I got some others going. So &amp;#8230; what?&lt;/p&gt;

&lt;p&gt;Why am I even writing this? I guess, because it&amp;#8217;s the one thing I feel like I need to do. Nothing else feels as important. I don&amp;#8217;t want to do anything else right now. I don&amp;#8217;t want to code anything. I don&amp;#8217;t want to send any fucking emails. I don&amp;#8217;t want to watch TV. I don&amp;#8217;t want to play any games. Am I melting down? My brain wants to let loose of something. What the fuck is it? Come the fuck out already?&lt;/p&gt;

&lt;p&gt;I want to get angry! Just let this shit out. But nothing&amp;#8217;s coming. I just keep typing stuff. The dubstep is really appealing to me right now. I stare at this screen and &amp;#8220;Caspa&amp;#8221; drones on in the background with my desk and walls reverberating. Caaaaasssppppaaaa.&lt;/p&gt;

&lt;p&gt;Whatever. I need some excitement I think. Something to get this body going. My mom recently hinted at some yoga/buddhist stuff. It said there are three types of people. I&amp;#8217;m not going to bother looking this shit up for a silly post, so from memory they are: Vatta, Pita (spelling?), and Kapha. I took a test and the test scored me with 9 parts Vatta, 12 parts Pita, and 12 parts Kapha. What the hell does that even mean? I can&amp;#8217;t even have a distinct personality type? I have to be a bunch of everything? I&amp;#8217;m a waif that needs to be warmed up because I&amp;#8217;m cold, but I&amp;#8217;m also some other contradicting bullshit. And to top that off, there are counter personality types for when you&amp;#8217;re in a phunk &amp;#8230; but, what the shit. Which funk am I even in. I&amp;#8217;m screwed.&lt;/p&gt;

&lt;p&gt;If I wrote some code write now, I&amp;#8217;d probably get into it, but I also know I have to get up early in the morning and when I get into coding I keep going and then I&amp;#8217;m tired the next day and the next week and then I get sick. So &amp;#8230; I sit. I debate with myself whether I should be productive and code. If not code, then what? I have some annoying internal drive to be productive. I have another internal drive that does not want me to be tired. I have too many drivers. I feel like I&amp;#8217;m in drivers-ed. Someone is sitting in my passenger seat with their very own steering wheel, brake, and gas pedal. Give it back to me! Don&amp;#8217;t even think about touching that! Where did you come from anyways? What do you want?&lt;/p&gt;

&lt;p&gt;Internal conflict is a bitch. I don&amp;#8217;t even want to edit this post, but &amp;#8230; no, I do want to edit this post. I need to leave me alone. Maybe this is all normal. Maybe I&amp;#8217;m normally crazy. I am cursed with indecision caused by a desire for a realistic perfection.&lt;/p&gt;

&lt;p&gt;I think my brain wants to escape from all of this reality. It&amp;#8217;s fed up and wants to me grab some surreality by the neck scruff and paint the walls with it. Splat. I think I, more than my productive counterparts whom I look upon with admiration and bewilderment, need this escape. I have two sides and they compete like crazy. I think the personality test proved that. I am no one thing. I have many sides. As much as I would like to be one for the routine simplicity of it - and at times I can be quite successful at being fruitfully, simplistically, productive with all my eggs hatching and with all my orderly ducks obeying - my biorhythms are such that I will have a proportional fall into a crest of surreality. My other half demands it. Sometimes I fall somewhere in the middle and for those brief moments I am normal?&lt;/p&gt;

&lt;p&gt;I have no idea what in the hell I&amp;#8217;m talking about.&lt;/p&gt;

&lt;p&gt;Did I ever mention I&amp;#8217;m afraid of dying. Bah &amp;#8230; that&amp;#8217;s an old story. Don&amp;#8217;t really feel like talking about it. Something in me wanted to. Probably my banality.&lt;/p&gt;

&lt;p&gt;Tomorrow, I will want to write more. However, my brain will tell me that I did my writing yesterday and sacrificed precious productive hours in order to do it. So I will tell myself I had better work. I will feel guilty for not working. But then I won&amp;#8217;t write. Conflict ensues. I feel blah about it and do nothing due to my weakness. Indecision is my kryptonite.&lt;/p&gt;

&lt;p&gt;Have I written long enough yet? Have I wasted enough time such that starting to code now will be pointless because it&amp;#8217;s well past 11p? Have I escaped my responsibilities for the day? Will I need to do this to give myself an excuse from working without feeling bad about doing nothing on my couch?&lt;/p&gt;

&lt;p&gt;Probably. Probably not.&lt;/p&gt;

&lt;p&gt;The best part is I&amp;#8217;m writing this on my fancy blog thing. This must mean I want people to read it and feel something. What do I want you to feel? I guess I want to know if you do feel and that if you do that you feel something like me or nothing like me? Maybe I&amp;#8217;m reaching out. Groping my way into the wild to find out who gives a shit. I don&amp;#8217;t think it&amp;#8217;s an attention grab. A large part of me really just wants to write this just to get out.&lt;/p&gt;

&lt;p&gt;Tomorrow I&amp;#8217;ll probably feel like a dork for writing it and putting it out. But, I&amp;#8217;m committing and deploying tonight so too late, you.&lt;/p&gt;

&lt;p&gt;Go to bed.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Genesis</title>
   <link href="http://gusg.us/life/genesis.html"/>
   <updated>2009-06-17T00:00:00-05:00</updated>
   <id>http://gusg.us/life/genesis</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;In the beginning there was the word and that word was Dog&lt;/strong&gt;. We&amp;#8217;re not sure why it was Dog or where even words came from at the time. For instance, no one spoke in the beginning &amp;#8230; really. Well, it&amp;#8217;s not what we would call speaking anyways. And for that matter there was no written language, so how could anyone have said this word was the word in written form or otherwise?&lt;/p&gt;

&lt;p&gt;Nonetheless, &lt;strong&gt;the word was Dog&lt;/strong&gt;. &lt;em&gt;Sigh&lt;/em&gt; &amp;#8230; or so we&amp;#8217;ve been told. It could have been that others believed there was another word or maybe even other words. Perhaps maybe even no word at all; an interesting thought if ever one was thunk. If the case were that other options did exist, why is it then that this is the word of words that did survive to be mentioned as being the word? Were there more in quantity who did hear this word? Did this word simply resonate with the majority; like a measure of quality? Was there another word that was the word until this word came along and showed why the other word was not as good as this word?&lt;/p&gt;

&lt;p&gt;And what happened to those that may not have had any word at all? Where are they? What is their fate? Outsiders looking in? Looking in on what? Does not having a word or words preclude one from being a part of worded universe?&lt;/p&gt;

&lt;p&gt;And of the nature of this word or words or even no-words, how was their meaning intended whence conceived or not-conceived? Did one have the word with them or was the word there for one to receive? In the case of no-words, was no word chosen, unchosen, or ilchosen?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Anyways&lt;/em&gt;, &lt;strong&gt;the word was Dog and the Dog was strong&lt;/strong&gt;. Neigh, not strong. The word was a hunter. This Dog did hunt. Have Dog must hunt. Of prey there were many. Of remains there were few. The size of the word doth not shadow the size of the mouth that speak it. All did succumb like krill in the ballooning mouth of an endlessly swimming whale. A whale through a void of people. Dog was a whale of a word.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Coming neverly soon: the mitosis of the word.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Gus Bus has a Flat</title>
   <link href="http://gusg.us/life/gusbus-has-a-flat.html"/>
   <updated>2009-06-01T00:00:00-05:00</updated>
   <id>http://gusg.us/life/gusbus-has-a-flat</id>
   <content type="html">&lt;p&gt;Recognized two lessons I had learned in life:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When you need help, suck it up and ask for it&lt;/li&gt;

&lt;li&gt;Most people like to help&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nate Sanders is one such person &amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Thumbly Going On</title>
   <link href="http://gusg.us/life/thumbly-going-on.html"/>
   <updated>2009-01-05T00:00:00-06:00</updated>
   <id>http://gusg.us/life/thumbly-going-on</id>
   <content type="html">&lt;p&gt;&lt;a href='http://www.youtube.com/watch?v=tEM3dW2oWW4'&gt;&amp;#8220;Nooooow, this&amp;#8217; a little story I got to tell &amp;#8230;&amp;#8221;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I normally play 3rd base in 12&amp;#8221; softball. I also live around Chicago. I&amp;#8217;m not just telling you that for nothing. This year, one of my buddies asked me to also play 3rd on his 16&amp;#8221; team. We&amp;#8217;re talking Chicago softball with the enormous balls (no giggling), shortened base paths, and no gloves. Half way into the season - October 2nd to be exact - it&amp;#8217;s the 1st inning of a game (meaning, the ball is still hard) and a guy slams a grounder in my direction. I field it normally, feel a pop in my left thumb, throw to first base, look down, and have a Salvador Dali moment; yeah, it was extremely surreal.&lt;/p&gt;

&lt;p&gt;I didn&amp;#8217;t panic, I just told the guys I needed to go, walked off the field, and grabbed my bag. They thought I might have dislocated it (a typical injury), buuuuuuuut I didn&amp;#8217;t and I did &lt;strong&gt;NOT&lt;/strong&gt; want to show anyone. Finally, somebody smart asked me if I was okay to drive, which kind of made me think, &amp;#8220;No. No I&amp;#8217;m not. My thumb isn&amp;#8217;t attached anymore&amp;#8221;.&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s right. I severed it. I broke the bone right in half at the top knuckle and nearly tore the whole top portion of that digit right off. Only some skin on the bottom of my finger kept it from rolling right off of my hand and onto the floor. One lonely Beastie it did almost be. Now you should be able to fully grasp the surreality I was in. No pain, though. Probably caused by the abundance of numbness.&lt;/p&gt;

&lt;p&gt;Needless to say, called an ambulance. Paramedics were ticked because they didn&amp;#8217;t understand the severity of the severance either. They too thought I had just dislocated it.&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;Side note: It&amp;#8217;s actually really hard to describe this injury. If you&amp;#8217;re ever in this situation, take a picture. I did and it&amp;#8217;s the only thing that connects the dots for people. No, I will &lt;strong&gt;NOT&lt;/strong&gt; post the picture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;Got the hospital; Loyola Medical, luckily. But not without some delay on the paramedics part. They just sat us there at the field in the ambulance for like 20 minutes. I passively aggressively mentioned to them several times that my thumb was no longer connected to myself like it used to be. But no, I was not in pain and therefore, paperwork first. I should also say that people in the ER certainly take their time when they think you only have a dislocated thumb.&lt;/p&gt;

&lt;p&gt;While in the ER, an x-ray machine operator came by with her roaming x-ray machine to take some &amp;#8230; x-rays. Like everyone else, she did not get the nature of the injury. She asked me to do some crazy stuff with my hand, including turning it over so the back side of my hand could rest on the machine because &amp;#8220;[she had] to get the x-ray&amp;#8221;. Well excuse me! My thumb needed to stay attached, lady! Needless to say, we didn&amp;#8217;t like each other much. Me the nuisance, her the torturer. It was a little bit like a showdown at the OK corral.&lt;/p&gt;

&lt;p&gt;I eyed her. She eyed me. I flinched. Damn!&lt;/p&gt;

&lt;p&gt;After several other curious nurses and aids came by - who all acted like they were supposed to be doing something for me, but really just wanted to complete the mental model they had put together in their head - somebody finally paid attention. I was told by the ER supervisor person that Chicago-based medical students have to specifically learn how to treat 16&amp;#8221; softball injuries because they are so common and so different from any other sport (the injuries, not the students). This was actually extremely fascinating to myself and my wife. I was also told that no one had ever severed their thumb during the act of performing recreational softball. Awesome!&lt;/p&gt;

&lt;p&gt;Fortunately for me, the really laid back resident and his intern did such an awesome job lining the joint back up (which happened to be broken in two places) and sewing everything back together that I have never needed surgery. I was subsequently told this process was called a reduction, to which the dictionary concurs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The act of remedying a dislocation or fracture by returning the affected part of the body to its original [host]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Felt more like a relief to me.&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;Side note: I had to receive a local anesthetic in my hand - apparently called a digital block, which made me giggle to no end. Well, when your thumb is not attached, the unattached portion does not receive this so-called numbing nectar. So, when they finally start sewing your thumb on, you can &amp;#8230; uhhhh &amp;#8230; feel everything. Okay, enough.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;After 3 months of healing and &amp;#8220;therapy&amp;#8221;, I now (as of today) have 4/7&amp;#8217;ths the range of motion in my knuckle that I once did. That&amp;#8217;s 40 degrees of movement at the left knuckle compared to 70 degrees in my perfectly fine right knuckle. This is of course assuming the two knuckles were at one point equals. For whatever reasons, I did not do a baseline measurement before I severed the thumb. The doc says &amp;#8220;six months is the point at which you&amp;#8217;ll see no more healing&amp;#8221;.&lt;/p&gt;

&lt;p&gt;Speaking of healing, I actually took pictures once a week (or there abouts) to capture a timeline of the healing process. I will likely post these as an update in the near future here.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3 id='update'&gt;Update&lt;/h3&gt;

&lt;p&gt;Surprise! I lied. I&amp;#8217;m not going to post the pictures here. I posted them to &lt;a href='http://flickr.com/jaknowlden'&gt;my Flickr account&lt;/a&gt;, but you have to be my friend to see them. If you&amp;#8217;re not my friend, then you know why &amp;#8230; don&amp;#8217;t you?!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Load Model</title>
   <link href="http://gusg.us/code/ruby/load-model.html"/>
   <updated>2009-01-03T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/load-model</id>
   <content type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href='http://github.com/thumblemonks/load_model'&gt;Load Model&lt;/a&gt; can be found on Git Hub :)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post is a long time in coming. I&amp;#8217;ve pretty much procrastinated on writing it for about a year and I&amp;#8217;m not even sure why. Only after reading the &lt;a href='http://www.rorsecurity.info/storage/rails_security_2.pdf'&gt;RoR Security Book&lt;/a&gt; today - and specifically the section on &lt;em&gt;Privilege Escalation&lt;/em&gt; - did I feel compelled and obligated to write about a Rails plugin turned gem that I wrote a year ago.&lt;/p&gt;

&lt;p&gt;Behold, &lt;a href='http://github.com/thumblemonks/load_model'&gt;Load Model&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s not going to cook you breakfast in the morning, but it is going to make your job easier for something you probably do all the time in your controllers. Load Model basically provides a concise macro - a glorified &lt;code&gt;before_filter&lt;/code&gt; - for finding and loading a model object based on one of the request parameters and setting it to an instance variable. Load Model will do this almost automatically so long as you are following a restful convention in your controllers.&lt;/p&gt;

&lt;p&gt;For instance:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;PeopleController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:person&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The above code will look for a parameter named &lt;code&gt;:id&lt;/code&gt; and use that to find a &lt;code&gt;Person&lt;/code&gt;. If &lt;code&gt;:id&lt;/code&gt; is provided and a &lt;code&gt;Person&lt;/code&gt; record is found (via a call like &lt;code&gt;Person.find_by_id(params[:id])&lt;/code&gt;), the record instance will be set to the &lt;code&gt;@person&lt;/code&gt; instance variable. It&amp;#8217;s that easy.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s essentially the same as saying:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;PeopleController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;before_filter&lt;/span&gt; &lt;span class='ss'&gt;:load_person&lt;/span&gt;
&lt;span class='kp'&gt;private&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;load_person&lt;/span&gt;
    &lt;span class='vi'&gt;@person&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Person&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find_by_id&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But wait, there&amp;#8217;s waaaaayyyyy more! Including an easy approach to dealing with the privilege escalation use case.&lt;/p&gt;

&lt;h3 id='waaaaayyyyy_more'&gt;Waaaaayyyyy More&lt;/h3&gt;

&lt;p&gt;If everything were as simple as shown in the example above, I probably would not have needed to write Load Model. (Un)Fortunately not everything is so simple.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a quick peek at all the options. Most of these are named the way they are to indicate how closely Load Model is tied to Active Record.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:class&lt;/code&gt; - An alternative class name to load the model from. Defaults to the singular name of the provided model name. Same thing as &lt;code&gt;:class_name&lt;/code&gt; for associations.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;:parameter_key&lt;/code&gt; - The key in the params hash to use to grab the lookup value from. Does not support nesting. Defaults to &lt;code&gt;:id&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;:foreign_key&lt;/code&gt; - Used as the column name/lookup key on the association. Defaults to &lt;code&gt;:id&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;:require&lt;/code&gt; - Tells Load Model to throw an error if no record was found. Defaults to &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;:except&lt;/code&gt; - Load Model will not execute when the actions listed in this array are invoked.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;:only&lt;/code&gt; - Load Model will only execute when the actions listed in this array are invoked. &lt;code&gt;:except&lt;/code&gt; has precedence over &lt;code&gt;:only&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;&lt;code&gt;:through&lt;/code&gt; - Tells Load Model to use an instance variable to load a record from instead of from the association class. &lt;code&gt;:through&lt;/code&gt; takes precedence over &lt;code&gt;:class&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following are the bulk of the use-cases for using Load Model and how to use it appropriately.&lt;/p&gt;

&lt;h2 id='privilege_escalation'&gt;Privilege Escalation&lt;/h2&gt;

&lt;p&gt;I&amp;#8217;m not going to wait around. I&amp;#8217;m going to jump to straight into privilege escalation and blow the whole enchilada right now. There&amp;#8217;s no point in building you up to this. You&amp;#8217;re smart! People like you! And anyways, it may be the only reason you&amp;#8217;ve read this far.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s say you have a nested resource; like Images which nests under People. You&amp;#8217;re routes and Image controller may look like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# Routes&lt;/span&gt;

&lt;span class='no'&gt;ActionController&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Routing&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Routes&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;draw&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
  &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;resources&lt;/span&gt; &lt;span class='ss'&gt;:people&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;people&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='n'&gt;people&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;resources&lt;/span&gt; &lt;span class='ss'&gt;:images&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='c1'&gt;# Images controller&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ImagesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='c1'&gt;# Oh boy, some code!&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, when someone wants to see an image for a specific person, a typical URL would look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://example.com/people/1/images/3&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You don&amp;#8217;t want some stranger just changing that 3 to some other integer and getting a peek at another user&amp;#8217;s bottle-cap collection photos. So, you only want to limit the set of photos that are searchable to the specified user&amp;#8217;s (who has an id of 1).&lt;/p&gt;

&lt;p&gt;With Load Model you can do this in two lines and it will work for all actions of the Images controller.&lt;/p&gt;

&lt;p&gt;Liquid error: Broken pipe&lt;/p&gt;

&lt;p&gt;Yes, order of macro definition does matter. And yes, &lt;code&gt;:through =&amp;gt; :person&lt;/code&gt; assumes there will be an instance variable named &lt;code&gt;@person&lt;/code&gt; for Load Model to find the image from. In this case, Load Model will do the following at run time:&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='vi'&gt;@image&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@person&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;images&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find_by_image_id&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;What&amp;#8217;s that you say? You only want to load images for actions that will actually provide the &lt;code&gt;:id&lt;/code&gt;? Oh, okay.&lt;/p&gt;

&lt;p&gt;Liquid error: Broken pipe&lt;/p&gt;

&lt;p&gt;What? You don&amp;#8217;t want to do anything unless you find the Person instance first and you want to bail out if no image is found? Well &amp;#8230; fine!&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ImagesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:person&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:parameter_key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:person_id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:require&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:image&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:through&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:person&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:require&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:only&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:show&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:edit&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:update&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:destroy&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Notice the addition of the &lt;code&gt;:require&lt;/code&gt; options.&lt;/p&gt;

&lt;p&gt;I think you get the point. In fact, that&amp;#8217;s how we at Thumble Monks do it and how Load Model wants you to do it.&lt;/p&gt;

&lt;p&gt;If you add the following to your &lt;code&gt;ApplicationController&lt;/code&gt;, you can handle the case when a required record is not found by Load Model or any other action/filter (when &lt;code&gt;:require =&amp;gt; true&lt;/code&gt;):&lt;/p&gt;

&lt;h3 id='advanced'&gt;Advanced&lt;/h3&gt;

&lt;p&gt;I bet you didn&amp;#8217;t think it could get more advanced. You were wrong.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s say you have a Communities resource, which has a nested Events resource, which has a nested Attendees resource. Oh boy! The route definition would look something like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='no'&gt;ActionController&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Routing&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Routes&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;draw&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
  &lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;resources&lt;/span&gt; &lt;span class='ss'&gt;:communities&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;communities&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='n'&gt;communities&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;resources&lt;/span&gt; &lt;span class='ss'&gt;:events&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;events&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='n'&gt;events&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;resources&lt;/span&gt; &lt;span class='ss'&gt;:attendees&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The URL would probably look like the following when doing something with a specific attendee:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://example.com/communities/1/events/3/attendees/5&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;#8217;s also assume you require users to login and when logged in, you set an instance variable called &lt;code&gt;@current_person&lt;/code&gt;. Here&amp;#8217;s how you could setup your Attendees controller to only find attendees of events of communities that the logged-in user has access to:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;AttendeesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:community&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:through&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:current_person&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:require&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='ss'&gt;:parameter_key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:community_id&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:event&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:through&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:community&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:require&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='ss'&gt;:parameter_key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:event_id&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:attendee&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:through&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:event&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:require&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:only&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:show&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:edit&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:update&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:destroy&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Yes it works and yes we are using this recipe. I have some ideas for how to make this even more concise/automatic, just haven&amp;#8217;t gotten around to implementing them yet. As you can imagine, there is a pattern.&lt;/p&gt;

&lt;p&gt;For example, it would be a lot cooler if I could do this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;AttendeesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:attendee&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:through&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='ss'&gt;:event&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='ss'&gt;:community&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:current_person&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;},&lt;/span&gt;
    &lt;span class='ss'&gt;:require&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:only&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:show&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:edit&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:update&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:destroy&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Load Model could also just assume that &lt;code&gt;:show, :edit, :update, :destroy&lt;/code&gt; will get an &lt;code&gt;:id&lt;/code&gt; by default.&lt;/p&gt;

&lt;h2 id='yeah_but_my_association_is_not_found_with_the_id_key'&gt;Yeah, but my association is not found with the :id key&lt;/h2&gt;

&lt;p&gt;Perhaps you want to find a record using a lookup key/column name other than &lt;code&gt;:id&lt;/code&gt;? To have an example to work from, let&amp;#8217;s say you deal with invitations and in the URL the invitee clicks from their email a UUID value is used in place of the &lt;code&gt;:id&lt;/code&gt;. The UUID value will likely be stored as a column on Invites named, oddly, &lt;code&gt;:uuid&lt;/code&gt;. The URL in the email would probably look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://example.com/invites/550e8400-e29b-41d4-a716-446655440000&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With Load Model, you would load up this invite like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;InvitesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:invite&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:foreign_key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:uuid&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is the equivalent to doing the following in your actions:&lt;/p&gt;

&lt;p&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='vi'&gt;@invite&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Invite&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find_by_uuid&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;All of the other options still work; like: &lt;code&gt;:require&lt;/code&gt;, &lt;code&gt;:only&lt;/code&gt;, etc.&lt;/p&gt;

&lt;h2 id='except_i_just_want_to_exclude_some_actions_from_load_model'&gt;Except, I just want to exclude some actions from Load Model&lt;/h2&gt;

&lt;p&gt;You may not like to use the &lt;code&gt;:only&lt;/code&gt; option for being explicit about the actions that need model loading. Maybe you have a whole bunch of actions in your morally bankrupt controller and it would be crazy to try and include them all. Fine. Load Model provides the &lt;code&gt;:exclude&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;Here is an example that excludes actions that would not need to accept the :id parameter.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ImagesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:image&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:except&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:index&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:new&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:create&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It should be noted that since we&amp;#8217;re not using the :require option, we&amp;#8217;re saying more than we need to. But, that&amp;#8217;s why this is an example.&lt;/p&gt;

&lt;h2 id='of_a_different_class'&gt;Of a different class&lt;/h2&gt;

&lt;p&gt;Finally, and probably least common, is the case when you want to load a record into an instance variable, but the class/model name for loading the record from cannot be inferred. For these cases, you use the &lt;code&gt;:class&lt;/code&gt; option and provide the class name that should be used.&lt;/p&gt;

&lt;p&gt;Example, and this one is way contrived at the moment, you want to load a user account in an Admin controller and you want to call the instance variable &lt;code&gt;@admin&lt;/code&gt;. You would simply do the following in Load Model:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ImagesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='n'&gt;load_model&lt;/span&gt; &lt;span class='ss'&gt;:admin&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:class&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;User&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:require&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I threw the &lt;code&gt;:require =&amp;gt; true&lt;/code&gt; since it&amp;#8217;s the administration controller ;)&lt;/p&gt;

&lt;h2 id='what_else'&gt;What else?&lt;/h2&gt;

&lt;p&gt;Please let me know if there are any obvious enhancements that can be made or if we&amp;#8217;re just being dumb about something. I&amp;#8217;ve never really seen anything quite like Load Model and I made sure I was &lt;strong&gt;NOT&lt;/strong&gt; reinventing the wheel here. I mean, I tried real hard not to.&lt;/p&gt;

&lt;p&gt;See the &lt;a href='http://github.com/thumblemonks/load_model'&gt;Readme&lt;/a&gt; on GitHub for notes on installation, licensing, and so forth.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Talking to God</title>
   <link href="http://gusg.us/code/ruby/talking-to-god.html"/>
   <updated>2008-12-20T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/talking-to-god</id>
   <content type="html">&lt;p&gt;I recently started writing my &lt;a href='http://github.com/thumblemonks/evoke'&gt;Evoke&lt;/a&gt; service (a nice, little &lt;a href='http://sinatra.rubyforge.org/'&gt;Sinatra&lt;/a&gt; app). Part of the Evoke service is actually delivering on the promise of calling a stored URL back, which I achieved by storing a runner as a &lt;a href='http://github.com/tobi/delayed_job'&gt;delayed job&lt;/a&gt;. Only half the battle is writing the consumer, though. The other half is ensuring that the runner is daemonized and that the daemon is restarted if ever it were to die. This is where &lt;a href='http://god.rubyforge.org/'&gt;god&lt;/a&gt; enters the picture.&lt;/p&gt;

&lt;p&gt;For the Evoke consumer, I wrote a little god script that I package with the Evoke bundle. This script is easily configured to run from the command like so (relative to the evoke source code):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;god -c config/evoke.god
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;With that, the consumer is running and will be restarted if ever it dies. With Evoke, I added a status page which can be accessed via the world-wide-web. Status just shows me a few things about the particular Evoke instance, like: a view of the last 10 callbacks, how many callbacks in total, how many coming up, are any callbacks still pending that should not be, etc.&lt;/p&gt;

&lt;p&gt;To this status page I also added a little checker to make sure the Evoke consumer was running. If running, I get a nice green &amp;#8220;running&amp;#8221;; else, I get a nasty red &amp;#8220;not running&amp;#8221;. Naturally - god being a ruby app and all - I wanted to ask god if it was running. As it turns out, this is not as straightforward as it would seem.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I see now that this article is going to be hard to get through without a lot of giggling on my part&lt;/em&gt;&lt;/p&gt;

&lt;h3 id='one_would_think'&gt;One would think&lt;/h3&gt;

&lt;p&gt;One would think that they could just require in the &lt;code&gt;god&lt;/code&gt; library and use the API to ask for the state of a particular job. In my head, I would do this from IRB:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;god&amp;#39;&lt;/span&gt;
&lt;span class='no'&gt;God&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;status&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;evoke_consumer&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='ss'&gt;:state&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:up&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But &amp;#8230; nope. No way that I could see that is. So I went digging through the source and eventually had to find my way to the god shell script that gets executed from the command line. Which then led me to &lt;code&gt;God::CLI::CommandLine&lt;/code&gt;. This is the only place where we can see the mysteries of god. &lt;code&gt;DRb&lt;/code&gt; droppings. The info I need being printed to standard out. Everything I need to make one call, but all wrapped into a command line interface. I clearly cannot call any methods here.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s also clear that god was not intended to be accessed through more than one interface, without a lot of redundant code. Basically, I am forced into command line mode or parsing the results of an execution, unless I want some hackery. Hackery it is. After a little playing around and dealing with permissions and such (which is very cool of DRb and god to take care of for me), I wrote this little method into my &lt;code&gt;Status&lt;/code&gt; class:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;consumer_running?&lt;/span&gt;
  &lt;span class='no'&gt;DRb&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;start_service&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;druby://127.0.0.1:0&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;server&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;DRbObject&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;nil&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;God&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Socket&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;socket&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;17165&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;

  &lt;span class='n'&gt;server&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;status&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;evoke_consumer&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;][&lt;/span&gt;&lt;span class='ss'&gt;:state&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='ss'&gt;:up&lt;/span&gt;
&lt;span class='k'&gt;rescue&lt;/span&gt; &lt;span class='no'&gt;DRb&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;DRbConnError&lt;/span&gt;
  &lt;span class='kp'&gt;false&lt;/span&gt;
&lt;span class='k'&gt;ensure&lt;/span&gt;
  &lt;span class='no'&gt;DRb&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;stop_service&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Most of that is straight up jacked from god (except for the &lt;code&gt;DRb.stop_service&lt;/code&gt; :o ). I don&amp;#8217;t see why that would be so hard for god to let me do with what I intended earlier:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='no'&gt;God&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;status&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;evoke_consumer&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Come on god! Get with the program!&lt;/p&gt;

&lt;p&gt;Anyways, I intend to fix god so that I can do that. Hopefully, the master of god will accept?!?! I may be way out of my mind here and there may be a much easier way to do this. If so, shoot me an email (see address in the footer) with the solution.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Poem - Boring Bed</title>
   <link href="http://gusg.us/life/boring-bed-poem.html"/>
   <updated>2008-12-20T00:00:00-06:00</updated>
   <id>http://gusg.us/life/boring-bed-poem</id>
   <content type="html">&lt;pre&gt;&lt;code&gt;Boring bed
empty spread
One lays down
nothing said

A beast waits long
for their soul to return
Until that time
no fire shall burn&lt;/code&gt;&lt;/pre&gt;</content>
 </entry>
 
 <entry>
   <title>Douglas Street Sports Bar &amp; Grill</title>
   <link href="http://gusg.us/life/larry-opens-bar.html"/>
   <updated>2008-12-15T00:00:00-06:00</updated>
   <id>http://gusg.us/life/larry-opens-bar</id>
   <content type="html">&lt;p&gt;My old friend Larry Mazurkiewicz opened a bar in Elgin, IL last Thursday (12/11/2008). This can only spell trouble for me as it&amp;#8217;s 5 minutes away!&lt;/p&gt;

&lt;p&gt;&lt;a href='http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=231+Douglas+Ave,+Elgin,+IL+60120&amp;amp;sll=42.03337,-88.236344&amp;amp;sspn=0.009371,0.015149&amp;amp;g=231+Douglas+Ave,+Elgin,+IL+60120&amp;amp;ie=UTF8&amp;amp;t=h&amp;amp;z=16&amp;amp;iwloc=addr'&gt;Address&lt;/a&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Douglas Street Bar
231 Douglas Ave
Elgin IL 60120&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id='update'&gt;Update&lt;/h4&gt;

&lt;p&gt;I&amp;#8217;m not saying Larry&amp;#8217;s old. I&amp;#8217;m just saying he&amp;#8217;s a friend that goes way back :)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Obama &amp; Einstein</title>
   <link href="http://gusg.us/life/obama-and-einstein.html"/>
   <updated>2008-11-30T00:00:00-06:00</updated>
   <id>http://gusg.us/life/obama-and-einstein</id>
   <content type="html">&lt;p&gt;This quote from Albert Einstein sums up Obama&amp;#8217;s campaign for me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We can’t solve problems by using the same kind of thinking we used when we created them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Albert Einstein&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks to &lt;a href='http://www.pragprog.com/users/display_profile/1131'&gt;Andy Hunt&lt;/a&gt; and his book &lt;a href='http://www.pragprog.com/titles/ahptl/pragmatic-thinking-and-learning'&gt;Pragmatic Thinking &amp;amp; Learning&lt;/a&gt; for turning me on to it.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Moving to Rails 2.2 Headaches - Vol 1</title>
   <link href="http://gusg.us/code/ruby/rails-2_2-headaches-1.html"/>
   <updated>2008-11-23T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/rails-2_2-headaches-1</id>
   <content type="html">&lt;p&gt;I had an itch in my butt to move our little app to the latest and greatest version of Rails - &lt;code&gt;2.2.2&lt;/code&gt;. It was really itching and against my better judgements, I dug right in there and went to picking at that itch.&lt;/p&gt;

&lt;p&gt;I went about my normal business of doing a &lt;code&gt;sudo gem install rails&lt;/code&gt; and then a &lt;code&gt;rake rails:freeze:gems&lt;/code&gt;. Simple enough. Started my tests and holy crap &amp;#8230; tests were failing left and right! I mean, come on now. This is silly. We are basically cutting edge without being on the Edge. We use all the latest and greatest plugins and stuff. What the hell&amp;#8217;s going on here?&lt;/p&gt;

&lt;p&gt;Being that I hate farting with functional tests, or really anything in Action Pack, I started with the unit tests. They&amp;#8217;re generally the easiest to resolve.&lt;/p&gt;

&lt;h3 id='shoulda'&gt;Shoulda&lt;/h3&gt;

&lt;p&gt;Shoulda was failing thanks the internationalization efforts. Our &lt;code&gt;should_ensure_length_in_range&lt;/code&gt; assertions were failing because the messages were expecting the old format. A look at &lt;a href='http://thoughtbot.lighthouseapp.com'&gt;Shoulda&amp;#8217;s tickets&lt;/a&gt; yielded a &lt;a href='http://thoughtbot.lighthouseapp.com/projects/5807/tickets/87-should_ensure_length_in_range-cant-work-with-rails22'&gt;promising fix&lt;/a&gt;. Thank goodness, too.&lt;/p&gt;

&lt;p&gt;From that fix, I pulled the attachment and just added it to our loaded libraries; as a temporary stop-gap until the Thoughbotters get around to a new release.&lt;/p&gt;

&lt;p&gt;Hey Thoughbotters, if you happen to read this, could you also patch in &lt;a href='http://thoughtbot.lighthouseapp.com/projects/8794-paperclip/tickets/49'&gt;Paperclip #49&lt;/a&gt;, &lt;a href='http://thoughtbot.lighthouseapp.com/projects/5807-shoulda/tickets/112'&gt;Shoulda #112&lt;/a&gt;, and &lt;a href='http://thoughtbot.lighthouseapp.com/projects/5807-shoulda/tickets/97'&gt;Shoulda #97&lt;/a&gt;? Mmmmmkay, thanks.&lt;/p&gt;

&lt;h3 id='haml'&gt;HAML&lt;/h3&gt;

&lt;p&gt;Out of the unit tests already and into the functionals. Fudge!&lt;/p&gt;

&lt;p&gt;My beloved HAML. How do I love thee. Already fixed up to support Rails &lt;code&gt;2.2.2&lt;/code&gt; in &lt;code&gt;2.0.4&lt;/code&gt;, but you never told me! Would have been helpful so I wasn&amp;#8217;t looking like an ass for 30 minutes.&lt;/p&gt;

&lt;p&gt;Anyways, HAML was broken because of a cool, new accessor added to ActionView called &amp;#8230; &lt;code&gt;output_buffer&lt;/code&gt;. And possibly from some other cool methods like &lt;code&gt;block_called_from_erb?&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I fiddled around for another 15 minutes until I remembered that I had to &lt;code&gt;rake gem:unpack&lt;/code&gt; it. We had frozen ourselves to &lt;code&gt;2.0.3&lt;/code&gt;. Doh!&lt;/p&gt;

&lt;p&gt;I am getting a bunch of these warnings from Rails now:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;DEPRECATION WARNING: @person will no longer be implicitly assigned to person. (called from tag at .../vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb:249)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thanks to this call:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;- render({:layout =&amp;gt; &amp;#39;person&amp;#39;}, :object =&amp;gt; @person) do
  = invite_key_tag&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Why I&amp;#8217;m getting the warnings is beyond me. I can only imagine that it has something do with line 258 of &lt;code&gt;action_view/base.rb&lt;/code&gt; which does not pass the &lt;code&gt;local_assigns&lt;/code&gt; around if also rendering with a layout.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;elsif options[:partial]
  render_partial(options) # 258&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Dear Rails, please stop this.&lt;/p&gt;

&lt;h3 id='smurf'&gt;Smurf&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://github.com/thumblemonks/smurf'&gt;I wrote it. I fixed it.&lt;/a&gt; Took 20 minutes. The Rails team got a little more clever and a little more OO about this one. &lt;a href='/code/ruby/smurf-rails-autominifying-js-css-plugin'&gt;Previously&lt;/a&gt;, asset inclusion went through a single &lt;code&gt;AssetTagHelper&lt;/code&gt; method. Now, we have full blown &lt;code&gt;ActionView::Helpers::AssetTagHelper::JavaScriptSources&lt;/code&gt; and &lt;code&gt;ActionView::Helpers::AssetTagHelper::StylesheetSources&lt;/code&gt; classes which each encapsulate some nice behavior. The &lt;a href='http://github.com/thumblemonks/smurf/commit/a45de3b84598ee61e274f1ae87a11850a09628ba#comments'&gt;code change&lt;/a&gt; for this fix is also less hacky, in my opinion.&lt;/p&gt;

&lt;p&gt;One other thing I discovered while running tests, &lt;code&gt;sqlite3&lt;/code&gt; doesn&amp;#8217;t just get added anymore. I had to add the following to my test helper setup:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.gem &amp;#39;sqlite3-ruby&amp;#39;, :lib =&amp;gt; &amp;#39;sqlite3&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thanks to Sam Schenkman-Moore&amp;#8217;s &lt;a href='http://weblog.rubyonrails.org/2008/11/21/rails-2-2-i18n-http-validators-thread-safety-jruby-1-9-compatibility-docs'&gt;comment #56&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='calendar_date_select'&gt;Calendar Date Select&lt;/h3&gt;

&lt;p&gt;Tim Charper was all over his &lt;a href='http://github.com/timcharper/calendar_date_select/commit/68bdbf598b2f0271df1301869fc6940333802d66'&gt;fix&lt;/a&gt; to &lt;a href='http://github.com/timcharper/calendar_date_select'&gt;calendar_date_select&lt;/a&gt;. Seems that &lt;code&gt;ActionView::Helpers::InstanceTag.new&lt;/code&gt; takes one less parameter now. The one where everyone was passing in &lt;code&gt;nil&lt;/code&gt; ;)&lt;/p&gt;

&lt;h3 id='calendar_builder'&gt;Calendar Builder&lt;/h3&gt;

&lt;p&gt;Tests were failing for the &lt;a href='http://github.com/collectiveidea/calendar_builder'&gt;calendar_builder&lt;/a&gt; plugin. I don&amp;#8217;t want to blame the &lt;a href='http://collectiveidea.com/'&gt;Collective Idea guys&lt;/a&gt; for this problem, though. They were using &lt;code&gt;CaptureHelper#capture&lt;/code&gt; in a class where they had included &lt;code&gt;CaptureHelper&lt;/code&gt;, obviously. And it worked fine prior to Rails &lt;code&gt;2.2&lt;/code&gt;. Post &lt;code&gt;2.1&lt;/code&gt;, however, this class suffered the same fate as pre-2.0.4 HAML, which is the curse of the dreaded &lt;code&gt;nil output_buffer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The problem was simply that their class - named &lt;code&gt;Week&lt;/code&gt; - was using &lt;code&gt;capture&lt;/code&gt;, but not rendering it in any context that had access to the actual &lt;code&gt;output_buffer&lt;/code&gt; instance variable. However, the calling method in &lt;code&gt;CalendarBuilder#calendar&lt;/code&gt; did. So, a few &lt;a href='http://github.com/jaknowlden/calendar_builder/commit/c5102ae881f812801fcd95ab104b9ea3c4b83a1d'&gt;tweaks to the yields and blocks&lt;/a&gt; and we were back on track.&lt;/p&gt;

&lt;p&gt;Sent them a pull request. They&amp;#8217;re very cool guys who respond pretty quickly; in case your anxious to get ahold of the latest copy.&lt;/p&gt;

&lt;p&gt;Also ran into a &lt;code&gt;sqlite3&lt;/code&gt; problem running their tests, but this time I only had to add this to their test helper:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem `sqlite3-ruby`&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id='routes'&gt;Routes&lt;/h3&gt;

&lt;p&gt;OMG. Just when I thought I was done; you know &amp;#8230; because all the tests were passing. I started the app up, sent my browser to &lt;code&gt;http://localhost:3000/&lt;/code&gt; and &amp;#8230; 405 error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Only post requests are allowed
...
vendor/rails/actionpack/lib/action_controller/routing/recognition_optimisation.rb:64:in `recognize_path&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;WTF? What now? Nothing had changed in our routes or anything. The last couple lines of our routes.rb looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  ...
  map.resource :session
  map.resource :dashboard
  map.root :dashboard
  map.connect &amp;#39;:controller/:action/:id&amp;#39;
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Worked before. &lt;code&gt;http://localhost:3000/&lt;/code&gt; should be trying to hit &lt;code&gt;DashboardsController#show&lt;/code&gt; and then be redirected to &lt;code&gt;SessionsController#new&lt;/code&gt; for not being logged in.&lt;/p&gt;

&lt;p&gt;Hmmm &amp;#8230;&lt;/p&gt;

&lt;p&gt;More hacking around. &lt;code&gt;http://localhost:3000/dashboard&lt;/code&gt; works fine and does the redirect. &lt;code&gt;http://localhost:3000/session/new&lt;/code&gt; does what it&amp;#8217;s supposed to, show the login page. Reading, reading, reading &amp;#8230; nothing. Tried watching the logs, but it only errored without telling me what it was trying to render.&lt;/p&gt;

&lt;p&gt;On an absolute whim, I wondered &amp;#8220;What if it&amp;#8217;s not even hitting show?&amp;#8221; The documentation never said anything about a routes change, but hey &amp;#8230; Rails documentation isn&amp;#8217;t the best. So, seriously on a whim, out of nowhere, for no reason but to try, I made this one change:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;map.resource :dashboard, :only =&amp;gt; [:show]&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Holy f&amp;#8217;ing crap! It worked. Back to normal. Whew &amp;#8230; &lt;code&gt;hg commit &amp;amp;&amp;amp; hg push&lt;/code&gt;. Yeah, we&amp;#8217;re using &lt;a href='http://www.selenic.com/mercurial/wiki/'&gt;Mercurial&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='summary'&gt;Summary&lt;/h3&gt;

&lt;p&gt;I don&amp;#8217;t know. I guess this is normal behavior. Maybe some suggestions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the stuff done you were trying to get done before you upgrade :(&lt;/li&gt;

&lt;li&gt;Make sure you have upgraded every single one of your dependencies and make sure you haven&amp;#8217;t frozen anything to an older version &amp;#8230; else you&amp;#8217;ll be chasing your tail&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='update'&gt;Update&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We&amp;#8217;re not using Mercurial anymore. We moved to git and are hosting on GitHub (private ya&amp;#8217;ll).&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>History Blog Meme</title>
   <link href="http://gusg.us/code/history-blog-meme.html"/>
   <updated>2008-11-12T00:00:00-06:00</updated>
   <id>http://gusg.us/code/history-blog-meme</id>
   <content type="html">&lt;p&gt;As seen on &lt;a href='http://objo.com/'&gt;Joe O&amp;#8217;Brien&amp;#8217;s&lt;/a&gt; blog, a &lt;a href='http://objo.com/2008/4/19/history-blog-meme'&gt;history blog meme&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;justin@gus:~&amp;gt; history 1000 | awk &amp;#39;{a[$2]++}END{for(i in a){print a[i] &amp;quot; &amp;quot; i}}&amp;#39; | sort -rn | head
109 rake
74 rakef
52 cl
48 hg
40 git
30 rakeu
25 cd
21 l
15 ri
11 erl&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Proof that I run tests more than I do anything else; e.g. &lt;code&gt;rake&lt;/code&gt;, &lt;code&gt;rakef&lt;/code&gt; (&lt;code&gt;rake test:functionals&lt;/code&gt;), and &lt;code&gt;rakeu&lt;/code&gt; (&lt;code&gt;rake test:units&lt;/code&gt;)!&lt;/p&gt;

&lt;p&gt;Having found &lt;code&gt;Cmd+k&lt;/code&gt; on my Mac, the &lt;code&gt;cl&lt;/code&gt; (aka &lt;code&gt;clear&lt;/code&gt;) call will stop.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Erlang Diaries - Vol 1</title>
   <link href="http://gusg.us/code/erlang/erlang-diaries-vol1.html"/>
   <updated>2008-11-12T00:00:00-06:00</updated>
   <id>http://gusg.us/code/erlang/erlang-diaries-vol1</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m starting a new diary for my forays into learning Erlang. Below are my first entries. I basically want to learn Erlang for a couple of reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It&amp;#8217;s a new language I don&amp;#8217;t know&lt;/li&gt;

&lt;li&gt;Functional languages interest me&lt;/li&gt;

&lt;li&gt;I enjoy agent-based modeling and simulation&lt;/li&gt;

&lt;li&gt;I want to write a Wator simulation in Erlang&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason for the final note can be traced back to a &lt;a href='http://groups.softwarecraftsmanship.org/'&gt;Software Craftsmanship&lt;/a&gt; meeting on November 10, 2008. Uncle Bob was talking about the &lt;em&gt;Total Cost of a Mess&lt;/em&gt; and showing off his old Java crapplet code for a Wator implementation. Dean Wampler then said, and I&amp;#8217;m paraphrasing, it would be interesting [for Gus] to implement Wator in Erlang.&lt;/p&gt;

&lt;h3 id='1111__1200'&gt;11/11 @ 12:00&lt;/h3&gt;

&lt;p&gt;Some tests were running while I was at work so I installed the Erlang Mac port. The install didn&amp;#8217;t work :( I had to modify the port to remove the &lt;code&gt;- hipe&lt;/code&gt; line. Thanks to &lt;a href='http://syntatic.wordpress.com/2008/06/12/macports-erlang-bus-error-due-to-mac-os-x-1053-update/'&gt;Brian Tatnall&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I also downloaded some documentation. Namely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Erlang Book - Part 1; [EB]&lt;/li&gt;

&lt;li&gt;Design Patterns for Simulations in Erlang/OTP; [PhD]&lt;/li&gt;

&lt;li&gt;Program Development Using Erlang - Programming Rules and Conventions, from Ericsson; [Zzzz]&lt;/li&gt;

&lt;li&gt;HTML Documentation provided with the port, same as on the site; [erl]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I haven&amp;#8217;t written or compiled a lick of code yet, haven&amp;#8217;t even really looked at the language. I know from past experiences that getting started is the slowest part of learning a language and that having documentation at your fingertips is the key to resolving it.&lt;/p&gt;

&lt;p&gt;See you later. Love you. &lt;em&gt;Golly &amp;#8230; I sure am excited&lt;/em&gt;&lt;/p&gt;

&lt;h3 id='1112__810'&gt;11/12 @ 8:10&lt;/h3&gt;

&lt;p&gt;I didn&amp;#8217;t get much sleep last night. Nothing to do with Erlang. I hit snooze like 3 or 4 times. I was already running late and sent an email to the team about it. Apparently my son had the same problem. I had to drive him to school, which made me late for my late train.&lt;/p&gt;

&lt;p&gt;Thusly, I had about 50 minutes to spare before the 8:55a train, which you know is not going to get there on time because American train systems suck and never get anywhere when they&amp;#8217;re supposed to; unless I&amp;#8217;m running almost late and get to the train a few minutes ahead only to find that that the smart train conductors were thinking kindly and got the train there ahead of me.&lt;/p&gt;

&lt;p&gt;All that said, time to spare. I &amp;#8220;opened&amp;#8221; [EB] and read through the Introduction. I really did this time. I&amp;#8217;ll prove it: Erlang was designed for use in concurrent, real-time systems. It was designed pragmatically while some phone geeks were putting together a phone system. The language only contains what is needed and it doesn&amp;#8217;t contain any of that gobbelty-gook sugar that sequential logic programming languages have. And it&amp;#8217;s fast.&lt;/p&gt;

&lt;p&gt;Next, I started chapter 1 entitled &lt;em&gt;Programming&lt;/em&gt;. Awwweeesuuummm. First page, code; to wit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-module(math1).
-export([factorial/1]).

factorial(0) -&amp;gt; 1;
factorial(N) -&amp;gt; N * factorial(N-1).&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I can type that into my editor, and did (actually, I copied it). Saved it as &lt;code&gt;ch1.erl&lt;/code&gt;. I added the &lt;code&gt;erl&lt;/code&gt; because I noticed there was a command of the same name and I figured I would be smart. &lt;code&gt;ch1&lt;/code&gt; means &amp;#8220;chapter 1&amp;#8221;. Oh, you betcha *wink*.&lt;/p&gt;

&lt;p&gt;Alright. Now to run it.&lt;/p&gt;

&lt;p&gt;Ok.&lt;/p&gt;

&lt;p&gt;Want to run it.&lt;/p&gt;

&lt;p&gt;Looking around for the next step; the running-it step.&lt;/p&gt;

&lt;p&gt;Still looking.&lt;/p&gt;

&lt;p&gt;[EB], help! Anything? What&amp;#8217;s that you say [EB]?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[EB]: How the code for factorial was compiled and loaded into the Erlang system is a local issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;Gus: WTF does that mean?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;[EB]: By ‘local issue’ we mean that the details of how a particular operation is performed is system-dependent and is not covered in this book.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;Gus: Uh huh &amp;#8230;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;[EB; page 10]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well &amp;#8230; that&amp;#8217;s not very helpful. What the hell is NOT system-dependent? Diary, Erlang made me so mad! I could have just poked it in the eye; but not too hard.&lt;/p&gt;

&lt;p&gt;I hacked around for while, farting with &lt;code&gt;erl&lt;/code&gt;. Got a lot of this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;** exception error: bad argument in an arithmetic expression
     in operator  &amp;#39;/&amp;#39;/2
        called as factorial / 1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; import(&amp;#39;./ch1&amp;#39;).
exception exit: { {bad_module_name,&amp;quot;./ch1&amp;quot;},[{shell,import,1}]}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; module(math1).
** exception error: undefined function shell_default:module/1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and this&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt; import(ch1).
ok
&amp;gt; math1:factorial(1).
** exception error: undefined function math1:factorial/1&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Doh! That last one with the &lt;code&gt;ok&lt;/code&gt; really got me. I swear to god I thought I had it. &lt;a href='http://www.youtube.com/watch?v=UJTi7KJPx_E'&gt;Khhhhaaaaannnnnnn&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Tried compiling with &lt;code&gt;erlc&lt;/code&gt;. It created a file called &lt;code&gt;ch1.beam&lt;/code&gt;. But &amp;#8230; didn&amp;#8217;t help. Don&amp;#8217;t know what to do with it and I have no stinking internet access because I&amp;#8217;m still at the train station and I don&amp;#8217;t have one of those cool cards that lets me connect over satellite or cellular signals. Wah!&lt;/p&gt;

&lt;p&gt;I have over 300 pages of documentation on Erlang. No lie. Where is the little bit of documentation that says, &lt;em&gt;&amp;#8220;If you&amp;#8217;d like to actually use this turd you just wrote, do this you big dumby &amp;#8230;&amp;#8221;&lt;/em&gt;? Or maybe &lt;em&gt;&amp;#8220;If on a machine that is inferior to one of the real-time embedded systems we wrote this language for, do this &amp;#8230;&amp;#8221;&lt;/em&gt;. Seriously! Is it truly that terrible? Does it make the documentation that is linked off the site so muddied up and offend so many of others&amp;#8217; sensibilities? I think not.&lt;/p&gt;

&lt;p&gt;Gobbelty-gook sugar sure would be &lt;em&gt;sweet&lt;/em&gt; right now :( If I ever get something running and then learn this language, I will feel soooooo elite .. barf.&lt;/p&gt;

&lt;p&gt;Done for now. Crying. I&amp;#8217;m sad and it&amp;#8217;s cold outside.&lt;/p&gt;

&lt;h3 id='1112__958'&gt;11/12 @ 9:58&lt;/h3&gt;

&lt;p&gt;Almost to the train station. Had a thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: When &lt;a href='http://annealer.org'&gt;Gabriel&lt;/a&gt; said he didn&amp;#8217;t like Erlang because of the syntax, what was I thinking about? Probably had something to do with unicorns, band-aids, and rock candy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id='1112__1942'&gt;11/12 @ 19:42&lt;/h3&gt;

&lt;p&gt;Diary,&lt;/p&gt;

&lt;p&gt;I finally got Erlang to compile something. It was our little factorial program and I did it on the way home today &amp;#8230; on the train not in the car. It all started when I did some digging into the docs that can be found with the port and ran across &amp;#8220;Getting Started With Erlang&amp;#8221; [GS]. With an unlikely name like that, it&amp;#8217;s no wonder I couldn&amp;#8217;t figure it out.&lt;/p&gt;

&lt;p&gt;Anyways, seems like I was almost there. I was missing one f&amp;#8217;ing character in this whole mess. The lower-case letter &amp;#8216;c&amp;#8217;. What does it do? Well, look at this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;justin@gus ~ &amp;gt; erl
Erlang (BEAM) emulator version 5.6.2 [source] [async-threads:0] [kernel-poll:false]

Eshell V5.6.2  (abort with ^G)
1&amp;gt; c(math1).
{ok,math1}
2&amp;gt; math1:factorial(1).
1
3&amp;gt; math1:factorial(10).
3628800
4&amp;gt; math1:factorial(100).
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yeah, it worked. I&amp;#8217;m happy again.&lt;/p&gt;

&lt;p&gt;Look! A unicorn with a band-aid on its corn and it&amp;#8217;s crapping rock candy throughout the land.&lt;/p&gt;

&lt;p&gt;Love you! Ok, ba bye.&lt;/p&gt;

&lt;p&gt;PS: I added a great picture.&lt;/p&gt;
&lt;img src='/images/articles/code/erlang/erlang-vol1-unicorn-bandaid.jpg' /&gt;
&lt;h2 id='update'&gt;Update&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;I no longer work at the place I did when I wrote this article.&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Shoulda: Making DRY even DRY-ier</title>
   <link href="http://gusg.us/code/ruby/shoulda-making-dry-even-dryier.html"/>
   <updated>2008-11-09T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/shoulda-making-dry-even-dryier</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m in love with &lt;a href='http://thoughtbot.com/projects/shoulda'&gt;Shoulda&lt;/a&gt;. Not like that! Come on! I love Shoulda like a pedicurist loves sandpaper. My job would be do-able, but it would suck without it. My hands would be all crackly and stink a lot more. Not to mention I&amp;#8217;d probably end up gouging the client and then hemorrhaging &amp;#8230; oh god!&lt;/p&gt;

&lt;p&gt;Anyways, Shoulda takes some of the pain of writing tests away by actually making the tests readable. Contexts let me scope setup and teardown the way I&amp;#8217;ve always wanted to. It&amp;#8217;s also very easy to generate &lt;code&gt;contexts&lt;/code&gt; and &lt;code&gt;should&lt;/code&gt; statements dynamically without all that &lt;code&gt;define_method&lt;/code&gt; cruft.&lt;/p&gt;

&lt;p&gt;Now, If I&amp;#8217;m writing some sort of web-app - like with Rails or Sinatra - a lot of my model and controller tests tend to look the same. By the same, I mean there is an obvious pattern. Our refactoring brainwashing tells us we need to DRY this up. One obvious way of doing this is to write our own Shoulda macros by extending &lt;code&gt;Test::Unit::TestCase&lt;/code&gt;, &lt;code&gt;ActionController::TestCase&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;I prefer to extend/mix-into things by writing my own module with the methods I want and extending or including that module into the class/module the methods are intended for. Like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Thumblemonks&lt;/span&gt;
  &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;User&lt;/span&gt;
    &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Shoulda&lt;/span&gt;

      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;should_ask_for_milk_and_cookies&lt;/span&gt;
        &lt;span class='c1'&gt;# do someting&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# Shoulda&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# User&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# Thumblemonks&lt;/span&gt;
&lt;span class='no'&gt;Test&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Unit&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;TestCase&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;Thumblemonks&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Shoulda&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I like this approach because it&amp;#8217;s easy to find out - in like a debugger session - all of the modules that are mixed-in into a specific class/module that give said class/module it&amp;#8217;s methods. I like this approach every time, not just for extending things for Shoulda. &lt;em&gt;Props to &lt;a href='http://github.com/danhodos'&gt;Dan Hodos&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, that being said, if I am going to add my own macros for a model test case (for instance), I do not like putting all of that code into the actual file containing the test case for the model. The standard approach I&amp;#8217;ve seen is to then put it in the &lt;code&gt;test_helper.rb&lt;/code&gt; file. I dislike this for two reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It mentally restricts me from writing a lot of macros because it mucks up &lt;code&gt;test_helper&lt;/code&gt;&lt;/li&gt;

&lt;li&gt;&lt;code&gt;test_helper&lt;/code&gt; should really just contain bootstrap code for all tests&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Today, however I hit upon something I liked. I created a folder under &lt;code&gt;test&lt;/code&gt; in my Rails app which I called &amp;#8230; wait for it &amp;#8230; &lt;code&gt;shoulda&lt;/code&gt;. That&amp;#8217;s right, &lt;code&gt;$RAILS_HOME/test/shoulda&lt;/code&gt;. Then, I did the following in my &lt;code&gt;test_helper.rb&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# including require_local_lib just because I use it everywhere&lt;/span&gt;
&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;require_local_lib&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;pattern&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='no'&gt;Dir&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;glob&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;File&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;dirname&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='bp'&gt;__FILE__&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;pattern&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;f&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='n'&gt;f&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='n'&gt;require_local_lib&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;shoulda/*.rb&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then, I started creating a new file in shoulda - as I needed it - for each model I was testing. For instance, I was testing a &lt;code&gt;Membership&lt;/code&gt; model and ended up creating &lt;code&gt;test/shoulda/membership.rb&lt;/code&gt;. Seems simple, but I did sooooo much test refactoring in the process and my test cases ended up looking insanely clean and readable.&lt;/p&gt;

&lt;p&gt;So, morals of the story are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use Shoulda, though you shoulda been doing it already &amp;#8230; &lt;a href='http://www.sadtrombone.com/'&gt;sad trombone&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Do break your shoulda macros into their own files&lt;/li&gt;

&lt;li&gt;Keep shtuff out of &lt;code&gt;test_helper&lt;/code&gt; that isn&amp;#8217;t helping bootstrap test cases&lt;/li&gt;

&lt;li&gt;Refactor your tests mercilessly &amp;#8230; but, you already knew that&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id='update'&gt;Update&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;I wrote this before shoulda included a mechanism for loading macros from a pre-defined directory (I think)&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Smurf</title>
   <link href="http://gusg.us/code/ruby/smurf-rails-autominifying-js-css-plugin.html"/>
   <updated>2008-11-08T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/smurf-rails-autominifying-js-css-plugin</id>
   <content type="html">&lt;img src='/images/articles/code/ruby/mini-thor.jpg' align='left' height='250' width='250' /&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href='http://github.com/thumblemonks/smurf'&gt;Smurf&lt;/a&gt; can be found on Git Hub :)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You know how Rails 2.x has this cool feature for bundling sets of Javascript or CSS files? Yeah, they call it something like &amp;#8230; &lt;code&gt;cache&lt;/code&gt;. Crazy. I know. It&amp;#8217;s cool and all, but why does not it also minify that content? I mean, it&amp;#8217;s not like the content is going to change. You&amp;#8217;re only really going to be using this caching approach in production. Why couldn&amp;#8217;t it just do the minification on the big, concatenated file before it saved it?&lt;/p&gt;

&lt;p&gt;Not understanding it, I went in search of those plugins which would do just what I want. I just knew they were out there. They were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Not going to make me do anything else than use &lt;code&gt;:cache&lt;/code&gt; in my &lt;code&gt;include&lt;/code&gt; and &lt;code&gt;link&lt;/code&gt; tags&lt;/li&gt;

&lt;li&gt;Not going make me turn any features on or setup any configuration do-hickeys&lt;/li&gt;

&lt;li&gt;Would minify Javascript and CSS&lt;/li&gt;

&lt;li&gt;Just going to minify content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yeah. No. Nothing to meet that criteria. I did find a &lt;a href='http://github.com/sbecker/asset_packager/tree/master'&gt;few&lt;/a&gt; &lt;a href='http://github.com/timcharper/bundle-fu/tree/master'&gt;implementations&lt;/a&gt;. A &lt;a href='http://sneer.org'&gt;friend&lt;/a&gt; also turned me onto a &lt;a href='http://github.com/lucianopanaro/rack-javascript-minifier/tree/master'&gt;Rack minifier&lt;/a&gt; which does make a lot of sense, if you&amp;#8217;re running Rack. But, nothing that just did what I wanted.&lt;/p&gt;

&lt;p&gt;So, as I&amp;#8217;ve told others, if you&amp;#8217;re going to be a critic you should at least try to do better. Ergo, &lt;a href='http://github.com/thumblemonks/smurf'&gt;Smurf&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='what_does_it_do'&gt;What does it do?&lt;/h2&gt;

&lt;p&gt;I did a little digging into Rails to find out how I could get what I want. It didn&amp;#8217;t take all that long. Just look in &lt;code&gt;ActionView::Helpers::AssetTagHelper&lt;/code&gt; for a private method called &lt;code&gt;join_asset_file_contents&lt;/code&gt;. This is the method that takes a list of files, joins their contents together and returns the concatenated content.&lt;/p&gt;

&lt;p&gt;Whoa. That&amp;#8217;s what I want! All of the content together. In one stream. With that, I can just run the combined content through an appropriate minifier.&lt;/p&gt;

&lt;p&gt;And I did. I found Uladzislau Latynski&amp;#8217;s &lt;a href='http://javascript.crockford.com/jsmin.rb'&gt;jsmin.rb&lt;/a&gt;, which is a port of Douglas Crockford&amp;#8217;s &lt;a href='http://javascript.crockford.com/jsmin.c'&gt;jsmin.c&lt;/a&gt; library. I adapted Uladzislau&amp;#8217;s code a little and suddenly had a JS minifier.&lt;/p&gt;

&lt;p&gt;But, what about a CSS minifier? I looked around a little, but nothing stood out as elegant, so I rolled my own. It may not be the best, but it&amp;#8217;s short and I can actually read what it&amp;#8217;s doing. For example, here&amp;#8217;s how I compress a stream of CSS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;content.compress_whitespace.remove_comments.remove_spaces_outside_block.
  remove_spaces_inside_block.trim_last_semicolon&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;#8217;ll just have to &lt;a href='http://github.com/thumblemonks/smurf/tree/master/lib/smurf/stylesheet.rb'&gt;look at the code&lt;/a&gt; to see how I do it. SPOILER ALERT: I do it with regular expressions! &lt;em&gt;(use your high-pitched theatrical voice for that part)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Because I Hijack (that&amp;#8217;s my contribution to software patterns &amp;#8230; Hijacking) the nifty Rails method that returns content and just return minified content, I don&amp;#8217;t need to do any friggin&amp;#8217; thing else. And neither do you.&lt;/p&gt;

&lt;p&gt;Install the plugin and you&amp;#8217;re done. Hell yeah!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./script/plugin install git://github.com/thumblemonks/smurf.git&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make sure you have this in at least your &lt;code&gt;production.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.action_controller.perform_caching = true&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then make sure you are using the &lt;code&gt;:cache&lt;/code&gt; option with your &lt;code&gt;javascript_include_tag&lt;/code&gt; and &lt;code&gt;stylesheet_link_tag&lt;/code&gt; statements.&lt;/p&gt;

&lt;h2 id='miscellany'&gt;Miscellany&lt;/h2&gt;

&lt;p&gt;I suggest &lt;a href='http://maintainable.com/articles/rails_asset_cache'&gt;this&lt;/a&gt; approach for cleaning up cached files if you need to do it for testing.&lt;/p&gt;

&lt;p&gt;However, a simple &lt;code&gt;cap deploy&lt;/code&gt; will &amp;#8220;get rid of&amp;#8221; of any cached files you have in production.&lt;/p&gt;

&lt;h2 id='references'&gt;References&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href='http://www.robertcasumbal.com/blog/?p=114'&gt;Mini Thor&lt;/a&gt; - Drawing by &lt;a href='http://www.robertcasumbal.com/'&gt;Robert Casumbal&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>The Me Me Meme</title>
   <link href="http://gusg.us/life/me-me-meme.html"/>
   <updated>2008-11-08T00:00:00-06:00</updated>
   <id>http://gusg.us/life/me-me-meme</id>
   <content type="html">&lt;img src='/images/articles/life/me-me-meme.jpg' height='375' width='500' /&gt;
&lt;p&gt;I was running around on the Internets just now and ran into &lt;a href='http://blog.matt-darby.com/'&gt;Matt Darby&amp;#8217;s&lt;/a&gt; &lt;a href='http://blog.matt-darby.com/2008/10/04/the-me-meme/'&gt;The Me Meme&lt;/a&gt; post. Alright, I&amp;#8217;ll do it.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Pay it forward instructions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take a picture of yourself right now&lt;/li&gt;

&lt;li&gt;Don’t change your clothes, don’t fix your hair…just take a picture. (should be super-easy with Photobooth)&lt;/li&gt;

&lt;li&gt;Post that picture with NO editing&lt;/li&gt;

&lt;li&gt;Post these instructions with your picture&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Dumb SMTP</title>
   <link href="http://gusg.us/code/ruby/dumb-smtp.html"/>
   <updated>2008-11-08T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/dumb-smtp</id>
   <content type="html">&lt;p&gt;I saw this post about a &lt;a href='http://d.hatena.ne.jp/koseki2/20081030/mocksmtpd'&gt;Mock SMTP&lt;/a&gt; server off of &lt;a href='http://rubyflow.com'&gt;RubyFlow&lt;/a&gt; today and it scared the living crap out of me. You bet it did! Is that what a mock of something is considered to be?&lt;/p&gt;

&lt;p&gt;In response, I&amp;#8217;m attaching the code for a dumb SMTP server that I wrote in less than two hours that I have used in my Rails applications to test what and to whom was getting mailed. All this little server does is respond with kind words; as in, it says &lt;code&gt;OK&lt;/code&gt; to everything it can. It&amp;#8217;s an eager server that will reaffirm everything you may have thought about SMTP.&lt;/p&gt;

&lt;p&gt;It also wouldn&amp;#8217;t be to hard to ask it to store the emails for grabbing later. It would certainly be a lot less code and a lot friggin&amp;#8217; easier to read.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class='c1'&gt;# I am a stupid SMTP server. Though I speak SMTP, all I do is regurgitate what&lt;/span&gt;
&lt;span class='c1'&gt;# the sender sends me. Use me for doing manual testing of SMTP clients that have&lt;/span&gt;
&lt;span class='c1'&gt;# simple needs.&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# Example usage:&lt;/span&gt;
&lt;span class='c1'&gt;#   dumb-smtp.rb localhost 25252&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# Then, have your client try and send email to localhost:25252 and watch the&lt;/span&gt;
&lt;span class='c1'&gt;# STDOUT of dumb-smtp. Theoretically, your client will think it actually sent&lt;/span&gt;
&lt;span class='c1'&gt;# the email and you can observe what your client actually sent.&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# Feel free to keep me simple by leaving me alone; unless you have some cool &lt;/span&gt;
&lt;span class='c1'&gt;# ideas.&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# I have been known to work extremely well with ActionMailer :)&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;socket&amp;#39;&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;SmtpResponder&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
    &lt;span class='vi'&gt;@data&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='vi'&gt;@closed&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='vi'&gt;@domain&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;handle&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;line&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;strip&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;more_data&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='vi'&gt;@data&lt;/span&gt;

    &lt;span class='n'&gt;command&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;data&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;split&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;command&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;command&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;downcase&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;gsub&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/ +/&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_sym&lt;/span&gt;
    &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;command&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;data&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;ehlo&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;domain&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='vi'&gt;@domain&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;domain&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;250 OK &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;domain&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;ok&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;info&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;250 OK &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;info&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;alias&lt;/span&gt; &lt;span class='ss'&gt;:mail&lt;/span&gt; &lt;span class='ss'&gt;:ok&lt;/span&gt;
  &lt;span class='k'&gt;alias&lt;/span&gt; &lt;span class='ss'&gt;:rcpt&lt;/span&gt; &lt;span class='ss'&gt;:ok&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;data&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;info&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@data&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;354 Start mail input; end with &amp;lt;CRLF&amp;gt;.&amp;lt;CRLF&amp;gt;&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;more_data&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;data&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='kp'&gt;nil&lt;/span&gt; &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;data&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;.&amp;quot;&lt;/span&gt;
    &lt;span class='vi'&gt;@data&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;250 OK data received&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;quit&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;data&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@closed&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;221 &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='vi'&gt;@domain&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; Service closing transmission channel&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;closed?&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='vi'&gt;@closed&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;method_missing&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;methodname&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;500 Syntax error, command unrecognized&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='n'&gt;server&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;TCPServer&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;open&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;ARGV&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;ARGV&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='k'&gt;while&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;socket&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;server&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;accept&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;socket&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;puts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;220 dumb-smtp.foo Service ready&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;responder&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;SmtpResponder&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
  &lt;span class='n'&gt;socket&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='vg'&gt;$stdout&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;puts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;-- &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;strip&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;response&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;responder&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;handle&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;response&lt;/span&gt;
      &lt;span class='vg'&gt;$stdout&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;puts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;lt;&amp;lt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='n'&gt;socket&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;puts&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;break&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;responder&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;closed?&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='n'&gt;socket&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;close&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='n'&gt;server&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you do as the comments say, you&amp;#8217;re golden. You can even tell your appropriate Rails configuration file to talk to the port you reference and it will work. You could do that like so in your &lt;code&gt;development.rb&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='no'&gt;ActionMailer&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;delivery_method&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='ss'&gt;:smtp&lt;/span&gt;
&lt;span class='no'&gt;ActionMailer&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;smtp_settings&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='ss'&gt;:address&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:port&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;25252&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:domain&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;foo.bar&amp;#39;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now, I should note that I wrote this while &lt;a href='http://centro.net'&gt;working for Centro&lt;/a&gt; &amp;#8230; my ex-employer, silly.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Canonical</title>
   <link href="http://gusg.us/code/ruby/canonical.html"/>
   <updated>2008-11-08T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/canonical</id>
   <content type="html">&lt;p&gt;I and a co-worker (Eric Schwartz) wrote &lt;a href='http://github.com/centro/canonical/tree/master'&gt;Canonical&lt;/a&gt; for &lt;a href='http://centro.net'&gt;Centro&lt;/a&gt; - my current employer. Canonical does for your Rails app what Postfix&amp;#8217;s &lt;a href='http://www.postfix.org/canonical.5.html'&gt;canonical&lt;/a&gt; would do for your sys-admin. But now, you have the control! Ha ha!&lt;/p&gt;

&lt;p&gt;Check out the README for everything you need to know.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Alright fine, Canonical is an ActionMailer extension that acts just like the Postfix utility of the same name. Essentially, Canonical lets you substitute the To, CC, and/or BCC email destinations with one of many replacements via a rule. It can be great for your integration and testing environments to direct all mail so that it is sent to a QA email address or something.&lt;/p&gt;

&lt;p&gt;You may add a canonical rule like the following to send any email from the system to any address to the QA email distribution list:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;TMail::Mail.add_canonical_override(/.*/, &amp;#39;qa@foo.bar&amp;#39;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Assuming you are working at Foo Bar, that rule will match any destination address that has any character in it - meaning, it matches everything - and will substitute the matched email with qa@foo.bar. This is the same as saying the following in Postfix’s canonical file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/.*/, qa@foo.bar&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What you should notice is that canonical expects to see a regular expression as the first argument. Passing in anything that does not respond to =~ will result in an error.&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>I Voted!</title>
   <link href="http://gusg.us/life/i-voted-2008.html"/>
   <updated>2008-11-04T00:00:00-06:00</updated>
   <id>http://gusg.us/life/i-voted-2008</id>
   <content type="html">&lt;p&gt;I voted! Yes I did. Got up at 5:45a because my wife was tossing and turning all night for some reason. Got to the same voting center I had voted at for 2 previous elections at around 6:15a. At neither of the previous two elections did I encounter a line. Not true of the 2008 election. 45 minute wait.&lt;/p&gt;

&lt;p&gt;Awesome!&lt;/p&gt;
&lt;center&gt;&lt;img src='/images/articles/life/i-voted.jpg' /&gt;&lt;/center&gt;</content>
 </entry>
 
 <entry>
   <title>A Call for Less Process</title>
   <link href="http://gusg.us/life/call-for-less-process.html"/>
   <updated>2008-10-21T00:00:00-05:00</updated>
   <id>http://gusg.us/life/call-for-less-process</id>
   <content type="html">&lt;p&gt;I happened to be reading the Metra&amp;#8217;s &lt;a href='http://metrarail.com/OTBL/current.pdf'&gt;Bi-level&lt;/a&gt; monthly newsletter the other day and noticed an odd post in the Sound Off section. Entitled, &amp;#8220;Take the high road?&amp;#8221;; the author (an impassioned rider) was venting about the fairness of the daily merging and exit strategy between the upper and lower levels of the bi-level train cars.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ll let Jeffrey explain his problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I love reading about the complaints people have, sometimes about the strangest things. Well, I&amp;#8217;m going to try to contribute to that:&lt;/p&gt;

&lt;p&gt;I personally have a problem with how people are too courteous to others while getting off the trains. You see, the upper level passengers, though there are fewer of them compared to the ground level, always get to merge while exiting at a one-to-one ratio with all the passengers on the main floor (sometimes even two-to-one since one person from each side of the upper level gets to go!). That then leads to the whole upper level clearing out before even the first three to four rows of passengers on the ground level getting off –it&amp;#8217;s pretty unfair if you ask me! I mean, so if you&amp;#8217;re in the last two to three rows of that cabin –forget it, you might as well sit down, have breakfast, read War and Peace if you&amp;#8217;re trying to get off quick –all the while you see the smirking faces of the upper level passengers as they get off without delay. I propose a four-to-one ratio be unofficially implemented, where the upper level passengers should wait before coming down and merging with all the other traffic. This would only be fair. Otherwise, I&amp;#8217;m going to start practicing my climbing skills to get myself up there so I can get off the train sooner!&lt;/p&gt;

&lt;p&gt;I write all this with a smirk on my face ––but honestly, it is my pet peeve!&lt;/p&gt;

&lt;p&gt;-Jeffrey Milwaukee District North&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What struck me most is that Jeffrey&amp;#8217;s answer to the problem was to ask the seeming authority for more process. Though he&amp;#8217;s the one with the problem, he wants the solution to be solved for him instead of him adjusting to the situation or solving the situation himself.&lt;/p&gt;

&lt;p&gt;This is an all too often seen habit of people in moderate-or-larger sized organizations. &amp;#8220;Fix it for me&amp;#8221; is a creature of complacency and when it rears its head, you &lt;strong&gt;need&lt;/strong&gt; to take notice.&lt;/p&gt;

&lt;p&gt;Jeffrey, perhaps you could take a different train or you could move to the front of the car if it bothers you so much. Personally, I have adjusted by actually sitting on the top as I noticed I got off much faster this way. You may also want to notice that the top level holds less than half the number of people that the bottom level does; so, it may actually be fair after all.&lt;/p&gt;

&lt;p&gt;Change your perspective or change your life.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>PSA: Renewing Illinois Registration without Renewal Notice</title>
   <link href="http://gusg.us/life/psa-illinois-sticker-renewal.html"/>
   <updated>2008-10-18T00:00:00-05:00</updated>
   <id>http://gusg.us/life/psa-illinois-sticker-renewal</id>
   <content type="html">&lt;p&gt;You live in Illinois?&lt;/p&gt;

&lt;p&gt;You need to get a new sticker for that license plate of yours (even though you also pay for the metal it&amp;#8217;s attached to)?&lt;/p&gt;

&lt;p&gt;You lost your renewal notice that they sent you in the email or you just plain never received it (yeah right)?&lt;/p&gt;

&lt;p&gt;No problem. Just head over to your local &lt;a href='http://www.cyberdriveillinois.com/departments/drivers/facilities/home.html'&gt;DMV&lt;/a&gt; with a drivers license (preferably yours) and something that shows your license plate number - such as last year&amp;#8217;s registration slip.&lt;/p&gt;

&lt;p&gt;Oh yeah, and bring a 100 friggin&amp;#8217; dollars to renew your privilege to drive unencumbered by the state, in the state.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails 2: Inflection for Address</title>
   <link href="http://gusg.us/code/ruby/rails-2-1-1-address-inflection.html"/>
   <updated>2008-10-16T00:00:00-05:00</updated>
   <id>http://gusg.us/code/ruby/rails-2-1-1-address-inflection</id>
   <content type="html">&lt;p&gt;Hey! I added an ActiveRecord model to a project today named &lt;code&gt;Address&lt;/code&gt;. It&amp;#8217;s exactly what you think it is and I want my Contacts in this project to have many addresses.&lt;/p&gt;

&lt;p&gt;Because we&amp;#8217;re so hip and cool on this project, we&amp;#8217;re using Thoughbot&amp;#8217;s &lt;a href='http://github.com/thoughtbot/factory_girl/tree/master'&gt;Factory Girl&lt;/a&gt; gem. Yeah. So, I ran my tests and BAM! got this error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1) Error:
    test: when something something something something &amp;quot;Address.count&amp;quot; from 1 to 0. (ContactTest):
    NameError: uninitialized constant Addres&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which can be traced to line 226 of Factory Girl&amp;#8217;s &lt;a href='http://github.com/thoughtbot/factory_girl/tree/master/lib/factory_girl/factory.rb'&gt;factory.rb&lt;/a&gt; file, which does the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;class_or_to_s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;respond_to?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:to_sym&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;class_or_to_s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;classify&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;constantize&lt;/span&gt;
&lt;span class='k'&gt;else&lt;/span&gt;
  &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Seems simple enough to solve. Perhaps we should change the inflector rules to &amp;#8230; say &amp;#8230; this:&lt;/p&gt;

&lt;p&gt;Yeah &amp;#8230; no! Still didn&amp;#8217;t work. Went out to eat. Came back. Tried this stupid, stupid, stupid thing and &amp;#8230; well &amp;#8230; it worked:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='no'&gt;ActiveSupport&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Inflector&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;inflections&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;inflect&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
  &lt;span class='n'&gt;inflect&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;singular&lt;/span&gt;&lt;span class='sr'&gt; /(ss)$/i&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;\1&amp;#39;&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Barf again!&lt;/p&gt;

&lt;p&gt;Hopefully nothing else is broken now.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Installing the MySql gem on a Mac</title>
   <link href="http://gusg.us/code/ruby/install-mysql-gem-on-mac.html"/>
   <updated>2008-10-10T00:00:00-05:00</updated>
   <id>http://gusg.us/code/ruby/install-mysql-gem-on-mac</id>
   <content type="html">&lt;p&gt;Installing the mysql gem on my Mac today was not so easy; or obvious. Probably because I have Mysql installed as a port (currently on version 5.0.51).&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s what I had to do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ARCHFLAGS=&amp;quot;-arch i386&amp;quot; sudo gem install mysql -- --with-mysql-config=/opt/local/lib/mysql5/bin/mysql_config &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Barf!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Universal Quotes - Going Way Back</title>
   <link href="http://gusg.us/life/universal-quotes.html"/>
   <updated>2008-09-11T00:00:00-05:00</updated>
   <id>http://gusg.us/life/universal-quotes</id>
   <content type="html">&lt;p&gt;Man, the &lt;a href='http://web.archive.org'&gt;Wayback Machine&lt;/a&gt; is awesome and scary all at the same time. It&amp;#8217;s awesome that one can build a true history of progress of the web and it&amp;#8217;s design. It&amp;#8217;s scary to find old stuff you&amp;#8217;ve actually caused. For instance, I found my &lt;a href='http://web.archive.org/web/19970731032532/www.iit.edu/~knowjus/'&gt;home page&lt;/a&gt; from when I was in college at &lt;a href='http://www.iit.edu'&gt;IIT&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hadn&amp;#8217;t seen that page in a loooooonnngggg time and it was definitely a blast from the past. One good thing did come out of it, though - besides being glad we no longer have to use the &lt;code&gt;FONT&lt;/code&gt; HTML tag (thank you CSS) - I found my page of universal quotes that I had kept track of while in college.&lt;/p&gt;

&lt;p&gt;While, not the best quotes in the world, there are some truisms and some truthiness to them all.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;#8220;All shoes are hollow&amp;#8221;&lt;/em&gt; - gus (that&amp;#8217;s me)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Everyone who goes to the beach dies&amp;#8221;&lt;/em&gt; - Mark McEachran&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;You couldn&amp;#8217;t live without *p&amp;#8221;&lt;/em&gt; - Prof. Roberge; a C instructor&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;You can&amp;#8217;t walk on the grass if there isn&amp;#8217;t any there&amp;#8221;&lt;/em&gt; - Mark McEachran&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Coffee isn&amp;#8217;t coffee &amp;#8216;til it&amp;#8217;s not&amp;#8221;&lt;/em&gt; - Disco Stu&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Get a browser that supports frames you loser&amp;#8221;&lt;/em&gt; - Andy; from Giant Step (he got fired)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;It&amp;#8217;s always better to beat someone to the punch then to be punched to the beat&amp;#8221;&lt;/em&gt; - Codemaster&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;It&amp;#8217;s really cool when your shit works&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;I wouldn&amp;#8217;t be me if I wasn&amp;#8217;t&amp;#8221;&lt;/em&gt; - Mark McEachran&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;If we do not succeed, we run the risk of failure&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;If it isn&amp;#8217;t gray, it&amp;#8217;s inferior&amp;#8221;&lt;/em&gt; - gus; thoughts on thinking&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;I don&amp;#8217;t claim to know everything, I just claim to know more than you&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;What a great invention the stop sign is &amp;#8230; how many lives has it saved&amp;#8221;&lt;/em&gt; - Codemaster&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;I wonder if he is using the same wind we are using&amp;#8221;&lt;/em&gt; - &lt;a href='http://www.imdb.com/title/tt0093779/'&gt;Inigo Montoya&lt;/a&gt;; still good&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;The best things in life are free&amp;#8221;&lt;/em&gt; - &lt;a href='http://lesfeministes.com'&gt;Amber&lt;/a&gt;; at the time, my future wife&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;We can not explain our capacity to explain&amp;#8221;&lt;/em&gt; - MacNamara&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;It was a typo at first, then I decided it was a message from mr id&amp;#8221;&lt;/em&gt; - Tool-man Tim; APE&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;When you&amp;#8217;re on speed .. caffeine does little for you&amp;#8221;&lt;/em&gt; - Tool-man Tim&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Fuck you i&amp;#8217;m venting&amp;#8221;&lt;/em&gt; - The Jen&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Friendly programmers need help&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Yes .. it is a race, and yes .. I always win&amp;#8221;&lt;/em&gt; - Mark McEachran&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Religion is just a good ad agency&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;It&amp;#8217;s not dumb .. it just doesn&amp;#8217;t have a lot of intelligence put behind it&amp;#8221;&lt;/em&gt; - Christian; my bro&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you didn&amp;#8217;t count, that&amp;#8217;s 23 of them.&lt;/p&gt;

&lt;h2 id='new_quotes'&gt;New quotes&lt;/h2&gt;

&lt;p&gt;These are the quotes I like from my time at &lt;a href='http://techni.cal.ly'&gt;Centro&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&amp;#8220;If information were a train, you would have wrecked it!&amp;#8221;&lt;/em&gt; - gus to Bertt&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;A circle is just a line with lots of angles.&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Everything, but no mayo&amp;#8221;&lt;/em&gt; - some guy in line at Potbelly&amp;#8217;s&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;&amp;#8216;I don&amp;#8217;t like soda!&amp;#8217;, &amp;#8216;You should drink pop instead&amp;#8217;&amp;#8221;&lt;/em&gt; - Evan F, then gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Brett only eats live worms&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;I mean, I&amp;#8217;ve been a female for ten years now&amp;#8221;&lt;/em&gt; - &lt;a href='http://centro.net/'&gt;Shawn R&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Head cheese getting moved towards packaging&amp;#8221;&lt;/em&gt; - Bill S&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;It&amp;#8217;s not a swear. It&amp;#8217;s bull shit. You ever see a bull shit in the woods? That&amp;#8217;s weird.&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Have you come to consensus with yourself?&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Pff&amp;#8230; Flash doesn&amp;#8217;t wear pants, that&amp;#8217;s why it&amp;#8217;s Flash!&amp;#8221;&lt;/em&gt; - gus&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Too much is like too little, only backwards&amp;#8221;&lt;/em&gt; - Bertt&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More to come, I&amp;#8217;m sure.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Sinatra: auto-handling any CSS</title>
   <link href="http://gusg.us/code/ruby/sinatra-autohandling-css.html"/>
   <updated>2008-08-28T00:00:00-05:00</updated>
   <id>http://gusg.us/code/ruby/sinatra-autohandling-css</id>
   <content type="html">&lt;h4 id='update'&gt;Update&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;I have included this functionality in my &lt;a href='http://github.com/thumblemonks/chicago'&gt;Chicago&lt;/a&gt; gem&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;My &lt;a href='http://annealer.org'&gt;buddy&lt;/a&gt; and I like .. no, love &amp;#8230; &lt;a href='http://www.imdb.com/title/tt0137523/'&gt;Fight Club&lt;/a&gt;; more the movie than the book. We can&amp;#8217;t help but quote it like &amp;#8230; all the damn time. We&amp;#8217;ll even use the quotes to express ourselves; especially those that start with &lt;em&gt;&amp;#8220;I am Jack&amp;#8217;s &amp;#8230;&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, we thought it would be a good idea to start a site called &lt;a href='http://iamjacks.org'&gt;I am Jack&amp;#8217;s&lt;/a&gt; to allow us and others to go this site and enter their phrases for the moment. We also figured it would be neat to watch Twitter&amp;#8217;s public timeline for such statements and report on them.&lt;/p&gt;

&lt;p&gt;But, that&amp;#8217;s NOT the point of this article. The point of this article is to highlight a little thing we did while implementing the site. See, we normally do stuff in Rails because, well, it&amp;#8217;s pretty easy. However, we wanted to do something new and do something simple.&lt;/p&gt;

&lt;h3 id='sinatra'&gt;Sinatra&lt;/h3&gt;

&lt;p&gt;Talk about simple. &lt;a href='http://sinatrarb.com'&gt;Sinatra&lt;/a&gt; rocks. But, that&amp;#8217;s still not the point of this article. The point of this article is to highlight this little thing. Remember?&lt;/p&gt;

&lt;p&gt;The little thing, and I do mean little, was to add a handler for CSS that can handle any stylesheet request. See, most of the examples for handling CSS in Sinatra look like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/stylesheet.css&amp;#39;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='n'&gt;content_type&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;text/css&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:charset&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;sass&lt;/span&gt; &lt;span class='ss'&gt;:stylesheet&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Or, they render the CSS directly in the app.&lt;/p&gt;

&lt;p&gt;I. Don&amp;#8217;t. Like. That.&lt;/p&gt;

&lt;p&gt;I want all my view related code in one place and I know that all my CSS will be handled the same way. In my app, I want to do this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;sinatra&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;catch_all_css&lt;/span&gt;

&lt;span class='c1'&gt;# handle everything else&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Which should run any resource that matches &lt;code&gt;*.css&lt;/code&gt; through a Sass builder. Easy peasy:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;catch_all_css&lt;/span&gt;
  &lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/*.css&amp;#39;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;header&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;text/css; charset=utf-8&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;sass&lt;/span&gt; &lt;span class='n'&gt;request&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;env&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;PATH_INFO&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;%r[\/(.+)\.css]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;to_sym&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Yep; it works. But, this solution only works well when the stylesheet is requested off the doc-root. If you want to handle &lt;code&gt;/stylesheets/*.css&lt;/code&gt;, you&amp;#8217;ll just have to modify the regular expression a little or get it through URI.&lt;/p&gt;

&lt;h3 id='possible_changes'&gt;Possible changes&lt;/h3&gt;

&lt;p&gt;You may not want to use Sass. Why you wouldn&amp;#8217;t want to I don&amp;#8217;t understand, but you just may not want to. Here is a possible modification to the above that may work.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;sinatra&amp;#39;&lt;/span&gt;

&lt;span class='n'&gt;catch_all_css&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:sass&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;catch_all_css&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;handler&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='ss'&gt;:render&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;/*.css&amp;#39;&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
    &lt;span class='n'&gt;header&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;text/css; charset=utf-8&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;resource&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;request&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;env&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;PATH_INFO&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;%r[\/(.+)\.css]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;to_sym&lt;/span&gt;
    &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;handler&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;resource&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='something_ive_heard'&gt;Something I&amp;#8217;ve Heard&lt;/h3&gt;

&lt;p&gt;I&amp;#8217;ve &lt;a href='http://www.gittr.com/index.php/archive/sinatra-splat-routes/'&gt;heard&lt;/a&gt; that a future version of Sinatra will allow me to get the value of the splats (the values matched by the asterisks of a route) from &lt;code&gt;params[&amp;#39;splats&amp;#39;]&lt;/code&gt;. If this is true, we could modify &lt;code&gt;catch\_all\_css&lt;/code&gt; to look like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;/*.css&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='n'&gt;sass&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;splat&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_sym&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Session Testing in Rails 2.1</title>
   <link href="http://gusg.us/code/ruby/rails-2-1-session-testing.html"/>
   <updated>2008-08-18T00:00:00-05:00</updated>
   <id>http://gusg.us/code/ruby/rails-2-1-session-testing</id>
   <content type="html">&lt;p&gt;I upgraded one of my Rails apps recently from Rails pre 2.1 to Rails 2.1. I had a couple of expected caveats that needed my attention; like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I was able to remove the use of my &lt;a href='/2008/1/18/flashback-to-flash-now'&gt;Flashback&lt;/a&gt; plugin because &lt;code&gt;Flash.now&lt;/code&gt; became testable&lt;/li&gt;

&lt;li&gt;I was able to use named_scope instead of has_finder&lt;/li&gt;

&lt;li&gt;et al&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, there was one little hitch in my tests that I was not expecting. One of my controller tests was adding a session variable and the controller was looking for that value. Problem was, it kept failing. But &amp;#8230; it used to pass.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s what my test code did look like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_update_should_clear_invite_code_from_session_on_success&lt;/span&gt;
  &lt;span class='vi'&gt;@request&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;invite_code&lt;/span&gt;
  &lt;span class='n'&gt;post&lt;/span&gt; &lt;span class='ss'&gt;:update&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
  &lt;span class='n'&gt;assert_nil&lt;/span&gt; &lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And then I was using it with my &lt;a href='/2008/1/9/assertsession'&gt;AssertSession&lt;/a&gt; plugin that I&amp;#8217;m waiting for &lt;a href='http://workingwithrails.com/person/5938-scott-woods'&gt;Scott Woods&lt;/a&gt; to add into &lt;a href='http://validaterequest.rubyforge.org/'&gt;AssertRequest&lt;/a&gt; (since he emailed me that he would &amp;#8230; ahem):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;update&lt;/span&gt;
  &lt;span class='n'&gt;assert_session&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
  &lt;span class='vi'&gt;@user&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find_invited&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Notice here that the reference to &lt;code&gt;invite_code&lt;/code&gt; is a symbol. As long I only try to access &lt;code&gt;invite_code&lt;/code&gt; using &lt;code&gt;Session&lt;/code&gt;&amp;#8217;s square-bracket method (&lt;code&gt;def \[\]\(key\)&lt;/code&gt;) &amp;#8230; then no problems; thanks to &lt;code&gt;HashWithIndifferentAccess&lt;/code&gt;. My &lt;code&gt;AssertSession&lt;/code&gt; plugin, however accesses &lt;code&gt;Session&lt;/code&gt;&amp;#8217;s &lt;code&gt;data&lt;/code&gt; function. It seems that &lt;code&gt;Session&lt;/code&gt; (or maybe just &lt;code&gt;TestSession&lt;/code&gt;) has turned all keys to strings. Thus, &lt;code&gt;AssertSession&lt;/code&gt; cannot match a symbol to a string.&lt;/p&gt;

&lt;p&gt;Well okay. I switched every one of the session keys to strings and - sadly - my tests are passing. Ho hum.&lt;/p&gt;

&lt;p&gt;For clarity&amp;#8217;s sake, here is the new code:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_update_should_clear_invite_code_from_session_on_success&lt;/span&gt;
  &lt;span class='vi'&gt;@request&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;invite_code&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;invite_code&lt;/span&gt;
  &lt;span class='n'&gt;post&lt;/span&gt; &lt;span class='ss'&gt;:update&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
  &lt;span class='n'&gt;assert_nil&lt;/span&gt; &lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;invite_code&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;update&lt;/span&gt;
  &lt;span class='n'&gt;assert_session&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;invite_code&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
  &lt;span class='vi'&gt;@user&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find_invited&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;invite_code&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Summer Reading '08: Better Together</title>
   <link href="http://gusg.us/life/summer-reading-08.html"/>
   <updated>2008-07-29T00:00:00-05:00</updated>
   <id>http://gusg.us/life/summer-reading-08</id>
   <content type="html">&lt;img class='article' src='/images/articles/life/summer-reading-cover.jpg' align='right' /&gt;
&lt;p&gt;Hey! Have you ever gone to the book store and - I don&amp;#8217;t know - stopped in the self-help section?&lt;/p&gt;

&lt;p&gt;No? Oh. Yeah, me either.&lt;/p&gt;

&lt;p&gt;But let&amp;#8217;s say you did. Just for shits and giggles you do it. What do you think you would see?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Self-help books.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Yep.&lt;/p&gt;

&lt;p&gt;Now; have you ever analyzed these titles?&lt;/p&gt;

&lt;p&gt;Oh yeah, that&amp;#8217;s tons of fun. It&amp;#8217;s a friggin&amp;#8217; riot! When they say self-help section, they don&amp;#8217;t mean the stuff IN the books; they mean the stuff ON the books. There are some real winners out there.&lt;/p&gt;

&lt;p&gt;A nice recurse down the &lt;a href='http://www.amazon.com'&gt;Amazon&lt;/a&gt; slide proves this point:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href='http://www.amazon.com/Not-Again-Please-Come-Home-comforting/dp/0595189709/ref=sr_1_6?ie=UTF8&amp;amp;s=books&amp;amp;qid=1217309150&amp;amp;sr=1-6'&gt;Not Again&amp;#8230;Please Come Home: You&amp;#8217;re not alone! A comforting guide for women who choose to love, and be with, the man who frequently forgets his way home. &amp;#8230; with it and feel more peace in your heart.&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.amazon.com/1200-Pick-Lines-Zahid-Zaman/dp/1419670875/ref=sr_1_4?ie=UTF8&amp;amp;s=books&amp;amp;qid=1217309573&amp;amp;sr=1-4'&gt;1200 Pick Up Lines&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.amazon.com/Being-Strong-Man-Woman-Wants/dp/0973695102/ref=pd_bxgy_b_img_b'&gt;Being the Strong Man a Woman Wants: Timeless Wisdom on Being a Man&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.amazon.com/gp/product/1555177611/ref=cap_pdp_dp_3'&gt;The Book of Mormon Made Easier, Part II&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.amazon.com/Just-Who-Will-You-Question/dp/1401323189/ref=sr_1_30?ie=UTF8&amp;amp;s=books&amp;amp;qid=1217309979&amp;amp;sr=1-30'&gt;Just Who Will You Be?: Big Question. Little Book. Answer Within.&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sure. Those are pretty funny. No no, they are funny. Really. &lt;em&gt;Mormon. Easier. Part 2.&lt;/em&gt; Seriously?!&lt;/p&gt;

&lt;p&gt;Did you happen to click on any of the links. Did you notice a little trick Amazon uses called &lt;em&gt;Better Together&lt;/em&gt;. This is where they put two books together and suggest that they complement each other &amp;#8230; and anyways - other people have bought them together; shouldn&amp;#8217;t you?&lt;/p&gt;

&lt;p&gt;That in mind - and remembering that I asked about actually being in the bookstore - just notice how I noticed the truly self-medicating effect the self-help section was when I was at &lt;a href='http://www.yelp.com/biz/borders-books-music-and-cafe-chicago-6'&gt;Borders&lt;/a&gt; just the other day (pictures below). Mind you, I didn&amp;#8217;t have Amazon&amp;#8217;s &lt;em&gt;Better Together&lt;/em&gt; in mind at the time - I discovered that while writing this post - when I decided to take a few pictures of some book titles that seemed to, well, tell a story when put together.&lt;/p&gt;

&lt;h3 id='threesomes_its_all_in_your_head'&gt;Threesomes. It&amp;#8217;s all in your head.&lt;/h3&gt;

&lt;p&gt;This was the one that kicked it all off. I was standing there with my &lt;a href='http://lesfeministes.com'&gt;wife&lt;/a&gt; and pointed it out. She laughed and I friggin&amp;#8217; &lt;strong&gt;KNEW&lt;/strong&gt; I was on to something.&lt;/p&gt;
&lt;img src='/images/articles/life/books/3s-all-in-your-head.jpg' height='300' width='400' /&gt;
&lt;h3 id='stop_whining_i_love_you'&gt;Stop whining. I love you.&lt;/h3&gt;

&lt;p&gt;That&amp;#8217;s a lesson one only learns after getting married.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;#8220;Babe, why aren&amp;#8217;t you listening to me?&amp;#8221;&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&amp;#8220;Babe, why did you throw my phone out the car window?&amp;#8221;&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&amp;#8220;Babe, don&amp;#8217;t make me change my vertically striped dress shirt and plaid shorts. They match, damn it. It&amp;#8217;s my life!&amp;#8221;&lt;/em&gt;&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&amp;#8220;Babe, whose boxers are these?&amp;#8221;&lt;/em&gt; :O&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyways &amp;#8230; if you stop whining, you&amp;#8217;ll actually see the love.&lt;/p&gt;
&lt;img src='/images/articles/life/books/stop-whining-i-love-you.jpg' height='300' width='400' /&gt;
&lt;h3 id='what_happy_women_know_how_to_duck_a_suckah'&gt;What happy women know. How to duck a suckah.&lt;/h3&gt;

&lt;p&gt;Nuf said!&lt;/p&gt;
&lt;img src='/images/articles/life/books/what-happy-women-know-how-to-duck-a-suckah.jpg' height='300' width='400' /&gt;
&lt;h3 id='hold_on_to_your_nuts_a_thousand_names_for_joy'&gt;Hold on to your NUTs. A thousand names for Joy.&lt;/h3&gt;

&lt;p&gt;The wife also laughed at this one. Oh yeah!&lt;/p&gt;
&lt;img src='/images/articles/life/books/hold-on-to-your-nuts-a-thousand-names-for-joy.jpg' height='300' width='400' /&gt;
&lt;h3 id='the_answer_only_a_theory'&gt;The Answer. Only a theory.&lt;/h3&gt;

&lt;p&gt;I knew it! I&amp;#8217;ve been saying that for years. I told my 5th grade teacher the same damn thing about the math test.&lt;/p&gt;
&lt;img src='/images/articles/life/books/the-answer-only-a-theory.jpg' height='300' width='400' /&gt;
&lt;h2 id='moving_on'&gt;Moving on&lt;/h2&gt;

&lt;p&gt;If you haven&amp;#8217;t figured it out, this was fun for me. I want to add more pictures and with a longer chaining of titles. We&amp;#8217;re talking 3 or more books to create a real story of these titles.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Joy is no Cubicles</title>
   <link href="http://gusg.us/work/joy-is-no-cubicles.html"/>
   <updated>2008-06-02T00:00:00-05:00</updated>
   <id>http://gusg.us/work/joy-is-no-cubicles</id>
   <content type="html">&lt;img class='article' src='/images/articles/work/red-stapler.jpg' align='right' height='300' width='400' /&gt;
&lt;p&gt;So &amp;#8230; I&amp;#8217;m sitting on the train, top shelf of a two &amp;#8220;story&amp;#8221; train. It&amp;#8217;s the end of the day and I&amp;#8217;m waiting for the train to move out of &lt;a href='http://tinyurl.com/3lnpl7'&gt;Union Station&lt;/a&gt; so I can go home.&lt;/p&gt;

&lt;p&gt;Someone sits next me. Ugh.&lt;/p&gt;

&lt;p&gt;Well, if they&amp;#8217;re going to sit next to me, I&amp;#8217;m going to invade their &lt;em&gt;bubble&lt;/em&gt; with my prying eyes. I know it&amp;#8217;s &lt;em&gt;unethical&lt;/em&gt;, but people do it to me; apparently my monitor is also their monitor.&lt;/p&gt;

&lt;p&gt;Anyways, what do I spy with my sneaky eyes? A single, &lt;code&gt;8.5 x 11&lt;/code&gt; sheet of paper in their hands. It still has the creases from folding the paper in half, in half again, and in half one more time so as to fit it into their pocket.&lt;/p&gt;

&lt;p&gt;Poor woman. Must have been her first day. I thought I could tell by her posture and utter lack of energy. Of course, this behavior could be indicative of someone suffering from repetitive boredom syndrome. But, nope. It was her first day. Sure of it.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m sure of it because of this paper she is holding. You see, like many other papers you have seen, this paper had words on it. These words were arranged into something we affectionately call a list. What&amp;#8217;s so different about this paper from other papers are the words at the very top, which read &lt;strong&gt;&lt;em&gt;Top 10 Rules for Working in Cubicles&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Oh my goodness!&lt;/em&gt;&lt;/strong&gt;, I screamed loudly in my head.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can NOT be serious!&lt;/em&gt;, came thundering into my mouth only to be quenched back.&lt;/p&gt;

&lt;p&gt;Some lame individual did not come up with 10 &amp;#8220;rules&amp;#8221; for people to work together in a cubicled environment, right?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Someone actually thought this was a GOOD idea?&lt;/em&gt;, says I to me.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What list oriented, organizationally uptight, anal retentive, rigid individual with abandonment related control issues believed this would solve inter-personal conflicts amongst co-workers?&lt;/em&gt;, again I thought.&lt;/p&gt;

&lt;p&gt;I want to turn away, buuutttt &amp;#8230; yeah, I&amp;#8217;m still curious. How inhumane is this Corporation X? Peering with my peripherally acute right eye, I could skim only five of the &lt;em&gt;headlines&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&amp;#8220;Have good scents&amp;#8221;&lt;/em&gt; - something about not wearing too much perfume&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&amp;#8220;Hit the right tune&amp;#8221;&lt;/em&gt; - try not to play your music too loud? Okay, DUH!&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&amp;#8220;Ask before borrowing&amp;#8221;&lt;/em&gt; - what grade is this?&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&amp;#8220;Curb casual conversation&amp;#8221;&lt;/em&gt; - or [shut-up and work you underpaid chimps]&lt;/li&gt;

&lt;li&gt;&lt;em&gt;&amp;#8220;Be a courteous guest&amp;#8221;&lt;/em&gt;, &lt;em&gt;&amp;#8220;knock before entering&amp;#8221;&lt;/em&gt; - it&amp;#8217;s a f*&amp;amp;$ing cubicle for crying out loud. Knock on what? &lt;em&gt;Ugh, excuse me. I knocked on your imaginary friggin&amp;#8217; door and you did not answer! So I decided to come in. Okay?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Blood pressure rising thanks to the coffee I had just before leaving.&lt;/p&gt;

&lt;p&gt;Yet, I felt bad for her. She must be taking this job for there are no others for her. It&amp;#8217;s highly likely this was temporary work and I feel even sorrier then. My wife did temp work for some time and she relayed to me on not just one occasion how mind numbingly retarded some of the work is.&lt;/p&gt;

&lt;p&gt;I really find it absolutely soul-crushing to work in a cubicled environment. I did it when I inadvertently worked for United Airlines. Not only do cubicles suck in terms of nurturing social relations, they breed a culture of separation. &amp;#8221;&lt;em&gt;What&amp;#8217;s mine is mine and what&amp;#8217;s yours is not mine so don&amp;#8217;t even think of bringing that over here&lt;/em&gt;&amp;#8221;, kind of stuff.&lt;/p&gt;

&lt;h2 id='10_rules_for_happy_work_life'&gt;10 Rules for Happy Work Life&lt;/h2&gt;

&lt;p&gt;Not wanting to leave it alone, I had to come up with my own list of 10 things all humans should strive for in the workplace. I didn&amp;#8217;t do it on the spot and give them to her. No no; I&amp;#8217;m not that smart. Though I did start the template for this post.&lt;/p&gt;

&lt;p&gt;Basically, remember these 10 things and also that there is no guarantee of happiness here, but you certainly can do much worse from this point.&lt;/p&gt;

&lt;h3 id='1_were_all_human'&gt;1. We&amp;#8217;re all human&lt;/h3&gt;

&lt;p&gt;So act like it. Unless you&amp;#8217;re working with robots, you&amp;#8217;re working with people. This also works in reverse; if you want a robot, don&amp;#8217;t hire a human. Humans are fallible. Having any other expectation makes &lt;strong&gt;you&lt;/strong&gt; the idiot, not them.&lt;/p&gt;

&lt;h3 id='2_grow_up'&gt;2. Grow up&lt;/h3&gt;

&lt;p&gt;We&amp;#8217;re also all adults, so we should all treat each other like such. Guidelines for behaving in groups are insulting.&lt;/p&gt;

&lt;p&gt;And if you&amp;#8217;re working with us Generation X&amp;#8217;ers (Gen-X) you must remember that we are anti-establishment to the core (most of us, anyways) and value individualism. Treating adults like children will cause headaches for you when the Gen-X&amp;#8217;ers do the exact opposite of what you want - just on sheer principle.&lt;/p&gt;

&lt;h3 id='3_trust_others'&gt;3. Trust others&lt;/h3&gt;

&lt;p&gt;You have to trust others or you&amp;#8217;ll go insane. You can&amp;#8217;t do it all yourself. If you don&amp;#8217;t trust anyone around you, find a new job or get a shrink on retainer.&lt;/p&gt;

&lt;h3 id='4_unless_your_building_heart_monitors_youre_not_building_heart_monitors'&gt;4. Unless your building heart monitors, you&amp;#8217;re not building heart monitors&lt;/h3&gt;

&lt;p&gt;So chill out! Acknowledgements to &lt;a href='http://gabriel.gironda.org/'&gt;Gabe Gironda&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='5_ever_heard_of_a_benevolent_dictator'&gt;5. Ever heard of a benevolent dictator?&lt;/h3&gt;

&lt;p&gt;Everyone has an agenda. Everyone knows everyone has an agenda. Forcing your agenda on others because you think you are in a position of authority will always never work.&lt;/p&gt;

&lt;p&gt;Remember the Gen-X thing.&lt;/p&gt;

&lt;h3 id='6_cheesy_phrases_make_we_want_to_ignore_you'&gt;6. Cheesy phrases make we want to ignore you&lt;/h3&gt;

&lt;p&gt;Like &amp;#8220;Have good scents&amp;#8221;. You put that on letter-head and be serious about it and I will no longer think what you say has any merit. The point of your rules is for me to not ignore them. If you want to appeal to my sensibility, use open dialogue. Appeal to my intelligence.&lt;/p&gt;

&lt;h3 id='7_people_over_process'&gt;7. People over process&lt;/h3&gt;

&lt;p&gt;Yeah, it&amp;#8217;s stolen from the Agile Manifesto, but i don&amp;#8217;t care. Processes only exist because of people.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I think therefore I am&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am people therefore I process&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It makes sense. Abandon process when it appears it is detrimental to the people. The musicians on Titanic still died; no matter how noble.&lt;/p&gt;

&lt;h3 id='8_no_cubicles'&gt;8. No cubicles&lt;/h3&gt;

&lt;p&gt;Get rid of those cubicles. Do not join a company that has them. If you are already there, tear those cubicles down. Dismantle them and let the company try and fire you.&lt;/p&gt;

&lt;p&gt;This isn&amp;#8217;t just &lt;a href='http://www.imdb.com/title/tt0151804/'&gt;Office Space&lt;/a&gt;, a co-worker and I actually did it at United; and yes, we still work together at our new job; and no, they didn&amp;#8217;t fire us.&lt;/p&gt;

&lt;p&gt;You see, we sat next to each other, but were separated by a cube wall, a window and wall behind us, and a sea of cubes in front of us. In order to talk face-to-face, either we stood on our chairs or we had to walk around the cubicle peninsula.&lt;/p&gt;

&lt;p&gt;One day we said, &lt;em&gt;I wish this wall was not here&lt;/em&gt;. The importance of the word &lt;strong&gt;wall&lt;/strong&gt; in that statement cannot be under-emphasized. What did we do? Well, we literally took the wall apart. It took 10 minutes and at the end of it we had a portal into each other&amp;#8217;s cube. The sense of liberation on my part was overwhelming. I did not fret for one moment the repercussions.&lt;/p&gt;

&lt;p&gt;The time saved was enormous and in time, the rest of the company took advantage of this causeway; this gateway to freedom. By this I mean the other employees actually used this portal to move across the space. What this means is that socialization happened. Take down a wall and people communicate.&lt;/p&gt;

&lt;p&gt;At my current &lt;a href='http://centro.net'&gt;job&lt;/a&gt;, we set up our development space with what we call &amp;#8220;dogbones&amp;#8221;. Thing of an elongated conference table with ends that make the table look like a cartoonish dog bone. We have four of them in our space and they seat anywhere from 6 to 8 people. Everyone faces inward towards each other and sits directly next to someone.&lt;/p&gt;

&lt;p&gt;No walls. No impedance. We&amp;#8217;re people, damn it, and we&amp;#8217;re acting like it.&lt;/p&gt;

&lt;h3 id='ugh__where_are_the_other_two_you_said_10'&gt;Ugh &amp;#8230; where are the other two? You said 10!&lt;/h3&gt;

&lt;p&gt;So what. Sue me. I said 10 and came up with 8. Maybe that&amp;#8217;s all we need. See item #7 if you still have questions.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Makin' Mash</title>
   <link href="http://gusg.us/code/ruby/map-to-hash.html"/>
   <updated>2008-05-31T00:00:00-05:00</updated>
   <id>http://gusg.us/code/ruby/map-to-hash</id>
   <content type="html">&lt;p&gt;We all know and love the &lt;code&gt;map&lt;/code&gt; method in Ruby (and other functional-ish languages). Given some list of objects, we get back an equal-sized array of potentially different objects. In Ruby we can &lt;code&gt;map&lt;/code&gt; against arrays, hashes, sets, etc.; basically, anything that is &lt;code&gt;Enumerable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From time-to-time, though, I need to convert some list of object into a hash. Ergo, I need to &lt;code&gt;map-to-hash&lt;/code&gt; or &lt;code&gt;mash&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For instance, let&amp;#8217;s say I want to map an array of User records to a hash with email addresses pointing to the User records? Without much thought I could write it this way:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;users&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:all&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;# Not smart :)&lt;/span&gt;
&lt;span class='n'&gt;hashed_users&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;users&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;inject&lt;/span&gt;&lt;span class='p'&gt;({})&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;acc&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='n'&gt;u&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; 
  &lt;span class='n'&gt;acc&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;u&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;email&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;u&lt;/span&gt;
  &lt;span class='n'&gt;acc&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I would rather do the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;users&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:all&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='c1'&gt;# Still not smart :)&lt;/span&gt;
&lt;span class='n'&gt;hashed_users&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;users&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;mash&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;u&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;u&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;email&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;u&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s not a &lt;strong&gt;HUGE&lt;/strong&gt; change, but it does let me &lt;em&gt;say&lt;/em&gt; what I want to &lt;em&gt;say&lt;/em&gt; without all the &lt;strong&gt;acc&lt;/strong&gt;umulator cruft.&lt;/p&gt;

&lt;h2 id='implementation'&gt;Implementation&lt;/h2&gt;

&lt;p&gt;Simple, straight forward, and usable by anything that is Enumerable.&lt;/p&gt;

&lt;h2 id='acknowledgements'&gt;Acknowledgements&lt;/h2&gt;

&lt;p&gt;After writing my &lt;code&gt;mash&lt;/code&gt;, I realized others have probably done this many times before and a quick search found the below posts (Ruby specific). I was actually wrong about my assumption. I only found one post. Of course, I didn&amp;#8217;t search very hard and other languages probably do the same.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href='http://snippets.dzone.com/posts/show/4805'&gt;Map array to hash&lt;/a&gt; - There are actually one too many loops in &lt;a href='http://snippets.dzone.com/user/vinterbleg'&gt;vinterbleg&amp;#8217;s&lt;/a&gt; implementation. And it&amp;#8217;s Array specific where it should be Enumerable generic.&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>JSON in Rails Just Annoyed Me</title>
   <link href="http://gusg.us/code/ruby/json-in-rails-just-annoyed-me.html"/>
   <updated>2008-05-25T00:00:00-05:00</updated>
   <id>http://gusg.us/code/ruby/json-in-rails-just-annoyed-me</id>
   <content type="html">&lt;p&gt;Man. I was really having fun coding up JSON responses in one of my Rails apps. Until, that is, I wanted to do something custom.&lt;/p&gt;

&lt;p&gt;Now, you might ask, &lt;em&gt;&amp;#8220;Why would you want to do something custom?&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To which I would reply, &lt;em&gt;&amp;#8220;Sigh. Because I&amp;#8217;m just that way.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;h2 id='get_on_with_it'&gt;Get on with it&lt;/h2&gt;

&lt;p&gt;Ok, I&amp;#8217;ve got this &lt;code&gt;ActiveRecord&lt;/code&gt; model called &lt;code&gt;Fact&lt;/code&gt;. &lt;code&gt;Fact&lt;/code&gt; has attributes &lt;code&gt;:key&lt;/code&gt; and &lt;code&gt;:value&lt;/code&gt; along with the other normal columns (i.e. &lt;code&gt;:id&lt;/code&gt;, &lt;code&gt;:created_at&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;p&gt;I want to use &lt;code&gt;Fact&lt;/code&gt; in one of my views and I export it to JSON. I only care about the &lt;code&gt;:key&lt;/code&gt; and &lt;code&gt;:value&lt;/code&gt; and the obvious solution is to:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;fact&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Fact&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;create&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:value&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;fact&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_json&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:only&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:key&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:value&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Which returns something like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;value&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Ok &amp;#8230; fine. I can do something with that, but &lt;code&gt;Fact&lt;/code&gt; is really an extension of some other model, which can have many &lt;code&gt;Facts&lt;/code&gt;. And I want to reference these facts by their name in a JavaScript object. I don&amp;#8217;t want to search through the objects looking for a matching key. I want a JavaScript Object that looks something like:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You might say, &lt;em&gt;&amp;#8220;Get over it!&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I would say, &lt;em&gt;&amp;#8220;No. This is what I want.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I also figured it would be easy to modify &lt;code&gt;Fact&lt;/code&gt; to return what I want. What I figured was that since I could call &lt;code&gt;to_json&lt;/code&gt; on an &lt;code&gt;ActiveRecord&lt;/code&gt;, the implementation of &lt;code&gt;to_json&lt;/code&gt; would actually recursively work its way through the hierarchy of attributes and associations and call &lt;code&gt;to_json&lt;/code&gt; on each of them. Thinking this was the case, I went and wrote my own &lt;code&gt;to_json&lt;/code&gt; on &lt;code&gt;Fact&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;What happened?&amp;#8221;&lt;/em&gt;, you ask.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Bupkiss&amp;#8221;&lt;/em&gt;, I say.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;What do you mean?&amp;#8221;&lt;/em&gt;, you persistently ask.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;What&amp;#8217;s with all the questions!&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The reason why nothing happens is because &lt;code&gt;to_json&lt;/code&gt; hands responsibility over to the &lt;code&gt;ActiveRecord::Serialization::Serializer&lt;/code&gt; class (ASS). &lt;code&gt;ASS&lt;/code&gt; in turn builds up its own Hash of keys and values that it grabs from the &lt;code&gt;ActiveRecord&lt;/code&gt; in question.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;NOT&lt;/strong&gt; what I would expect. Hence, my annoyance. In fact, I find it a little silly and a little broken. If this is what I expected, I would instead pass an instance of &lt;code&gt;Fact&lt;/code&gt; to a JSON encoder and &lt;code&gt;Fact&lt;/code&gt; would in fact know nothing of JSON. As it stands, &lt;code&gt;Fact&lt;/code&gt; knows about JSON and JSON knows about &lt;code&gt;Fact&lt;/code&gt; (by knowing about &lt;code&gt;ActiveRecord&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id='whatchu_goan_do'&gt;Whatchu goan do?&lt;/h2&gt;

&lt;p&gt;I don&amp;#8217;t know yet. I&amp;#8217;ll repost when I figure it out. I just wanted to post my annoyance. I am very, very annoyed.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Only Losers are UNC Fans - With Tests</title>
   <link href="http://gusg.us/life/only-losers-are-unc-fans.html"/>
   <updated>2008-02-06T00:00:00-06:00</updated>
   <id>http://gusg.us/life/only-losers-are-unc-fans</id>
   <content type="html">&lt;p&gt;I&amp;#8217;m a Duke basketball fan; there, I admitted it. I didn&amp;#8217;t always like them, though. I have loved Kentucky since I was a little kid; in large part because of Rick Pitino and because they were just plain good and because I grew up in Ohio when there weren&amp;#8217;t any good teams.&lt;/p&gt;

&lt;p&gt;In that time, Duke beat Kentucky on many occasions causing me much angst. But as I got older I began to respect Duke if only for Coach K. He&amp;#8217;s such a damn good coach. He can take any rag-tag team of somebody&amp;#8217;s and turn them into an even better team.&lt;/p&gt;

&lt;p&gt;My mistake was telling a few UNC fans (and I do mean Duke&amp;#8217;s neighbor) at work that I was a Duke fan. All hell broke loose.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Duke sucks&amp;#8221;&lt;/em&gt; was the consistent mantra of the group. And lonely me; sitting there &amp;#8230; having to take it &amp;#8230; because I&amp;#8217;m just oh so humble and non-confrontational.&lt;/p&gt;

&lt;p&gt;They went so far as to tell me in code how they felt about it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='c'&gt;# This test is guaranteed to pass! &lt;/span&gt;
def test_justin_is_a_nancy
  &lt;span class='nv'&gt;justin&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; HoopsFan.find&lt;span class='o'&gt;(&lt;/span&gt;:nancy &lt;span class='o'&gt;=&lt;/span&gt;&amp;gt; &lt;span class='nb'&gt;true&lt;/span&gt;&lt;span class='o'&gt;)&lt;/span&gt; 
  assert_equal “Fairweather Nancy”, justin.real_name 
end
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So, of course it is my Pride&amp;#8217;s duty to respond. Here is the proof that all UNC fans are also losers:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;def test_only_losers_are_unc_fans
  &lt;span class='nv'&gt;losers&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; HoopNuts.find&lt;span class='o'&gt;(&lt;/span&gt;:all, :conditions &lt;span class='o'&gt;=&lt;/span&gt;&amp;gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;kast = ?&amp;#39;&lt;/span&gt;, &lt;span class='s1'&gt;&amp;#39;loser&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;])&lt;/span&gt;
  &lt;span class='nv'&gt;unc_fans&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; HoopNuts.find&lt;span class='o'&gt;(&lt;/span&gt;:all, :conditions &lt;span class='o'&gt;=&lt;/span&gt;&amp;gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;team = ?&amp;#39;&lt;/span&gt;, &lt;span class='s1'&gt;&amp;#39;UNC&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;])&lt;/span&gt;

  assert_same losers, unc_fans
  assert losers.length &amp;gt; 0
end
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;If you don&amp;#8217;t know already, it&amp;#8217;s Ruby with ActiveRecord sprinklings.&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Multiplexing Delegator</title>
   <link href="http://gusg.us/code/ruby/multiplexing-delegator.html"/>
   <updated>2008-01-27T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/multiplexing-delegator</id>
   <content type="html">&lt;p&gt;I&amp;#8217;ve got a &lt;code&gt;User&lt;/code&gt;, see, and this &lt;code&gt;User&lt;/code&gt; has a fever. And the only prescription for this fever is more &lt;code&gt;Network&lt;/code&gt; (get &lt;a href='http://www.vimeo.com/17746'&gt;even more fever&lt;/a&gt;). In fact, this &lt;code&gt;User&lt;/code&gt; already has two &lt;code&gt;Networks&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Network&lt;/span&gt;
  &lt;span class='c1'&gt;# The idea is that each of the accessors has an array of Users&lt;/span&gt;
  &lt;span class='kp'&gt;attr_accessor&lt;/span&gt; &lt;span class='ss'&gt;:active&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:pending&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:rejected&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;User&lt;/span&gt;
  &lt;span class='kp'&gt;attr_accessor&lt;/span&gt; &lt;span class='ss'&gt;:friend_network&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:public_network&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
    &lt;span class='vi'&gt;@friend_network&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='vi'&gt;@public_network&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;This is, of course, a very simplified implementation of a solution that might be built in Rails with ActiveRecord.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s awesome. I can work with each of these &lt;code&gt;Networks&lt;/code&gt; by adding to and removing from each of them individually. But, what if I wanted the list of all &lt;code&gt;Users&lt;/code&gt; that a particular User is linked to and I don&amp;#8217;t care which Network they are in?&lt;/p&gt;

&lt;p&gt;I could do this if I wanted all of the active users:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;friend_network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;active&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;public_network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;active&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Or, I could push the logic into the model as would be expected; like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;User&lt;/span&gt;
  &lt;span class='c1'&gt;# ...&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;all_active_users&lt;/span&gt;
    &lt;span class='vi'&gt;@friend_network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;active&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='vi'&gt;@public_network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;active&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;#8217;s fine. But what if I wanted the list of all rejected &lt;code&gt;Users&lt;/code&gt;? What if I wanted to add more feverish &lt;code&gt;Networks&lt;/code&gt;? A lot more code, that&amp;#8217;s what!&lt;/p&gt;

&lt;h2 id='interpretation'&gt;Interpretation&lt;/h2&gt;

&lt;p&gt;So, of course, a solution is forthcoming. What I really want to do is delegate a single message across multiple receivers and aggregate the results into a single response. Kind of like I&amp;#8217;m multiplexing messages and demultiplexing the response.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s an example of what I would like to do given a User instance:&lt;/p&gt;

&lt;p&gt;What should happen in this call is that &lt;code&gt;entire_network&lt;/code&gt; should know how to call &lt;code&gt;active&lt;/code&gt; on both the &lt;code&gt;friend_network&lt;/code&gt; and &lt;code&gt;public_network&lt;/code&gt; accessors, and then collect the results into a single collection of Users.&lt;/p&gt;

&lt;p&gt;Thusly and so forth, the &lt;code&gt;Multiplexing Delegator&lt;/code&gt; has been born. Let the dust settle a little &amp;#8230; and here is how I would define the &lt;code&gt;User&lt;/code&gt; class:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;User&lt;/span&gt;
  &lt;span class='kp'&gt;attr_accessor&lt;/span&gt; &lt;span class='ss'&gt;:friend_network&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:public_network&lt;/span&gt;

  &lt;span class='n'&gt;multiplex&lt;/span&gt; &lt;span class='ss'&gt;:entire_network&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:across&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:friend_network&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:public_network&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
    &lt;span class='vi'&gt;@friend_network&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
    &lt;span class='vi'&gt;@public_network&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Network&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Assuming &lt;code&gt;friend_network&lt;/code&gt; contains 3 &lt;code&gt;Users&lt;/code&gt; and &lt;code&gt;public_network&lt;/code&gt; contains 5 &lt;code&gt;Users&lt;/code&gt;, a call to &lt;code&gt;entire_network&lt;/code&gt; will return an array with 7 &lt;code&gt;Users&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='application'&gt;Application&lt;/h2&gt;

&lt;p&gt;I know what you&amp;#8217;re saying, &lt;em&gt;&amp;#8220;Sure. It works great for your example, but what else is it useful for?&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And I say, &lt;em&gt;&amp;#8220;I don&amp;#8217;t really care all that much since it&amp;#8217;s useful for me in this instance.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But really, that&amp;#8217;s not true. I do care; lest I wouldn&amp;#8217;t have gone through all this effort to impress you. I see can &lt;code&gt;mutliplex&lt;/code&gt; as being useful for aggregating any and many collections easily into one stream of results. Generally, the types of Objects being delegated to will be the same, but this does not have to be true.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s something fun I did:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Object&lt;/span&gt;
  &lt;span class='n'&gt;multiplex&lt;/span&gt; &lt;span class='ss'&gt;:all_methods&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
    &lt;span class='ss'&gt;:across&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:public_methods&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:protected_methods&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:private_methods&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='n'&gt;obj&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Object&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
&lt;span class='n'&gt;obj&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;all_methods&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='o'&gt;.]&lt;/span&gt; &lt;span class='c1'&gt;# Produced an array of all of the methods&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;No &amp;#8230; it does not match what is returned from &lt;code&gt;Object.methods&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;Simple and easy:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='n'&gt;install&lt;/span&gt; &lt;span class='n'&gt;multiplexing_delegator&lt;/span&gt;
&lt;span class='c1'&gt;# or if you&amp;#39;re boring&lt;/span&gt;
&lt;span class='n'&gt;sudo&lt;/span&gt; &lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='n'&gt;install&lt;/span&gt; &lt;span class='n'&gt;multiplexing_delegator&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://glomp.rubyforge.org/multiplexing_delegator'&gt;Documentation&lt;/a&gt; is served from &lt;a href='http://rubyforge.org/projects/glomp'&gt;RubyForge&lt;/a&gt;, just like the &lt;a href='http://glomp.rubyforge.org/svn/multiplexing_delegator'&gt;source code&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Readability and Performance is Beautiful Code</title>
   <link href="http://gusg.us/code/beautiful-code-readability-performance.html"/>
   <updated>2008-01-21T00:00:00-06:00</updated>
   <id>http://gusg.us/code/beautiful-code-readability-performance</id>
   <content type="html">&lt;p&gt;Had a &lt;em&gt;nice&lt;/em&gt; email discussion amongst the &lt;a href='http://techni.cal.ly'&gt;Centronians&lt;/a&gt; the other day about what beautiful code is. The discussion came about due to a challenge I put out to the team to improve a certain nested conditional branch in the &lt;a href='http://identity-matcher.googlecode.com/svn/trunk/lib/identity_matcher.rb'&gt;Identity Matcher&lt;/a&gt; method, &lt;code&gt;match_foaf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Seems as though there are some strong opinions from some that readability of code is secondary to the performance of code. I figured I would some up my thoughts and did so in the following matrix:&lt;/p&gt;
&lt;img src='/images/articles/code/code-perf-read.png' /&gt;
&lt;p&gt;To be clear, this is the code in question:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;foaf&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;has_key?&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;lt;&amp;gt;&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;knows&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;foaf&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;][&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;lt;http://xmlns.com/foaf/0.1/knows&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;knows&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;
    &lt;span class='n'&gt;knows&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;know&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;foaf&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;has_key?&lt;/span&gt; &lt;span class='n'&gt;know&lt;/span&gt;
        &lt;span class='n'&gt;person_id&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;foaf&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;know&lt;/span&gt;&lt;span class='o'&gt;][&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;lt;http://xmlns.com/foaf/0.1/Person&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;person_id&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;person_id&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
          &lt;span class='n'&gt;person&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;foaf&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;person_id&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]]&lt;/span&gt;
          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;person&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;http://xmlns.com/foaf/0.1/nick&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;person&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;http://xmlns.com/foaf/0.1/nick&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
            &lt;span class='n'&gt;nicks&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;person&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;http://xmlns.com/foaf/0.1/nick&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
          &lt;span class='k'&gt;end&lt;/span&gt;
          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;person&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;http://xmlns.com/foaf/0.1/member_name&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;person&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;http://xmlns.com/foaf/0.1/member_name&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;
            &lt;span class='n'&gt;names&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;person&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;&amp;lt;http://xmlns.com/foaf/0.1/member_name&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
          &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Keep an eye on &lt;a href='http://slickorslack.com'&gt;Slick or Slack&lt;/a&gt; for this little piece of code I threw up &lt;a href='http://slickorslack.com/codes/100'&gt;there&lt;/a&gt;. If my assumption is right, it will be one of the slackest of all.&lt;/p&gt;

&lt;h2 id='update'&gt;Update&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Slick or Slack no longer exists :(&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Active Record Modeling Life</title>
   <link href="http://gusg.us/life/active-record-modeling-life.html"/>
   <updated>2008-01-18T00:00:00-06:00</updated>
   <id>http://gusg.us/life/active-record-modeling-life</id>
   <content type="html">&lt;p&gt;A quick observation I made about how &lt;code&gt;ActiveRecord&lt;/code&gt; can be used to model life.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;class Life &amp;lt; ActiveRecord::Base
  has_many :causes
  has_many :effects, :through &lt;span class='o'&gt;=&lt;/span&gt;&amp;gt; :causes
end
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Flashback</title>
   <link href="http://gusg.us/code/ruby/flashback.html"/>
   <updated>2008-01-17T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/flashback</id>
   <content type="html">&lt;h4 id='update'&gt;Update&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;This is old news. Rails 2.x makes this a moot point.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;I love the &lt;code&gt;Flash.now&lt;/code&gt; mechanism. I love it with a weird passion. It really lets me DRY up my views in regards to message handling, while also allowing me to keep my controller code straight forward. I basically have one way to handle messages and all I have to do is add a &lt;code&gt;.now&lt;/code&gt; to my &lt;code&gt;flash&lt;/code&gt; reference when I don&amp;#8217;t want to do a redirect.&lt;/p&gt;

&lt;p&gt;But &amp;#8230; there&amp;#8217;s always a but &amp;#8230; I also love tests. I love tests with an even weirder passion than I love &lt;code&gt;Flash.now&lt;/code&gt;. And if you know anything about &lt;code&gt;Flash.now&lt;/code&gt; and Rails tests, then you know where I&amp;#8217;m going with this; I can&amp;#8217;t test &lt;code&gt;Flash.now&lt;/code&gt; variables in my functional tests!&lt;/p&gt;

&lt;p&gt;You say, &lt;em&gt;&amp;#8220;Say what?!&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I say, &lt;em&gt;&amp;#8220;It&amp;#8217;s true.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You say, &lt;em&gt;&amp;#8220;Yeah, I know. It&amp;#8217;s also sad.&amp;#8221;&lt;/em&gt; But wait, there&amp;#8217;s the article called &lt;a href='http://wiki.rubyonrails.org/rails/pages/HowToTestFlash.Now'&gt;How to test flash.now&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I say, &lt;em&gt;&amp;#8220;Yeah, but that&amp;#8217;s dumb.&amp;#8221;&lt;/em&gt; Why should I have to test a seemingly isomorphic mechanism in two different ways?&lt;/p&gt;

&lt;p&gt;You might say, &lt;em&gt;&amp;#8220;Because Flash.now basically discards variables passed into it so that at the end of the request, the get swept-up by the chain of sweepers.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I &lt;strong&gt;know&lt;/strong&gt; I would say, &amp;#8220;True. But I don&amp;#8217;t really care. These are tests.&amp;#8221; And anyways, I hate, hate, hate using &lt;code&gt;assert_tag&lt;/code&gt; in functional tests. Save it for integration tests.&lt;/p&gt;

&lt;p&gt;Finally, I would say, &lt;em&gt;&amp;#8220;I wrote this fancy plugin called Flashback which solves my problem.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You say, &lt;em&gt;&amp;#8220;Oh.&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;h2 id='interpretation'&gt;Interpretation&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Flashback&lt;/code&gt; is four useful lines of magic and wonder rolled into a big ball of &lt;strong&gt;plugin&lt;/strong&gt;. I went through many iterations in my head for how I wanted to implement it, but I went with the following for my objectives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The solution should only have effect in tests. It should not implicitly weave its way into production behavior.&lt;/li&gt;

&lt;li&gt;I should be conscious when the behavior is in affect.&lt;/li&gt;

&lt;li&gt;It should require very little effort on my part to enable the feature&lt;/li&gt;

&lt;li&gt;It should be simple&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With that in mind, I hit the court and started playing. Of course, I knew it was going to be a plugin, so I just went ahead and created the plugin. Being a tester, I wrote several functional tests for how I wanted it to work. They looked something like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;FlashersControllerTest&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActionController&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;TestCase&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_flash_available_after_request&lt;/span&gt;
    &lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='ss'&gt;:index&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:actual_flash&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_flash_now_not_available_after_request&lt;/span&gt;
    &lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='ss'&gt;:index&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;world&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;assert_nil&lt;/span&gt; &lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;now&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_flash_now_is_available_after_request_via_flashed&lt;/span&gt;
    &lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='ss'&gt;:index&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;world&amp;#39;&lt;/span&gt;
    &lt;span class='n'&gt;assert_equal&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;world&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flashed&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Three erroring tests. Oh, joy! I love errors when they come immediately after writing my test code. Notice the &lt;code&gt;flashed&lt;/code&gt; method call in test 3. That&amp;#8217;s my contribution to the world of &lt;code&gt;Flash&lt;/code&gt;. I want it to mean, give me the variables that were flashed (or flushed) during the request. Like a flash of light; fizzled and forgotten.&lt;/p&gt;

&lt;p&gt;Guess I should implement the faux Controller:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;FlashersController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;index&lt;/span&gt;
    &lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;now&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='n'&gt;render&lt;/span&gt; &lt;span class='ss'&gt;:text&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;blah&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Two passing tests, and an erroring test. Yippee! Just need to make that &lt;code&gt;flashed&lt;/code&gt; do something. Here, I went through many, many trials and tribulations. For like, almost 30 minutes. That is, until I figured, &lt;em&gt;&amp;#8220;Why not just insert my own Flash hash into the session for the request?&amp;#8221;&lt;/em&gt; Like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;FlashedHash&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActionController&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Flash&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;FlashHash&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;flashed&lt;/span&gt;
    &lt;span class='vi'&gt;@flashed&lt;/span&gt; &lt;span class='o'&gt;||=&lt;/span&gt; &lt;span class='p'&gt;{}&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;discard&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='kp'&gt;nil&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;flashed&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='k'&gt;super&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Hmmm &amp;#8230; and to accomplish objective (2), I would need to set that up somehow. Objective (3) says it should be easy to use. So, I settled on a little method that would be available in &lt;code&gt;Test::Unit::TestCase&lt;/code&gt;, that is dependent on there being a &lt;code&gt;TestRequest&lt;/code&gt; instance assigned to a &lt;code&gt;@request&lt;/code&gt; instance variable (which there always is for functional tests), and that would be named &amp;#8230; &lt;code&gt;flashback&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;flashback&lt;/span&gt;
  &lt;span class='vi'&gt;@request&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;flash&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;FlashedHash&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This, however, required a drastic change in my test; which went from two lines, to three.&lt;/p&gt;

&lt;p&gt;And, I had to write another test to be sure that &lt;code&gt;flashed&lt;/code&gt; was not available when &lt;code&gt;flashback&lt;/code&gt; wasn&amp;#8217;t called:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_no_flashback_means_flash_now_not_available_after_request_via_flashed&lt;/span&gt;
  &lt;span class='n'&gt;get&lt;/span&gt; &lt;span class='ss'&gt;:index&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;world&amp;#39;&lt;/span&gt;
  &lt;span class='n'&gt;assert_raise&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;NoMethodError&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flashed&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:actual_flash_now&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I wrote a couple of other tests, but you get the point. Call &lt;code&gt;flashback&lt;/code&gt; before you test your action and after &lt;code&gt;@request&lt;/code&gt; is defined, and Bob&amp;#8217;s your uncle!&lt;/p&gt;

&lt;h2 id='application'&gt;Application&lt;/h2&gt;

&lt;p&gt;You might not believe this, but I had an actual use for this little plugin immediately after writing it. In a certain Rails application I am working on, I have controllers with actions that render a page when an error occurs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;#8220;Amazing&amp;#8221;&lt;/em&gt;, you say.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s the standard &lt;code&gt;new -&amp;gt; create&lt;/code&gt; or &lt;code&gt;edit -&amp;gt; update&lt;/code&gt; paradigm. When an error occurs in the create/update actions, I put errors in the flash.now hash as &amp;#8230; can you guess it &amp;#8230; &lt;code&gt;:errors&lt;/code&gt;. Whenever &lt;code&gt;flash[:errors]&lt;/code&gt; exists while rendering a view, I do something special with it; like display it &amp;#8230; &lt;em&gt;&amp;#8220;Oooooooooo&amp;#8221;&lt;/em&gt;, say the martians.&lt;/p&gt;

&lt;p&gt;So, I want to test my &lt;code&gt;flash.now&lt;/code&gt; variables. I like the idea of setting &lt;code&gt;flashback&lt;/code&gt; when I need it, versus all the time with a &lt;code&gt;setup&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s the first place I used it; an action for creating &lt;code&gt;Stickies&lt;/code&gt;, which are kind of like user-to-user comments, but different &amp;#8230; sort of.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;test_create_should_flash_error_on_failure&lt;/span&gt;
  &lt;span class='n'&gt;user&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;users&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:quentin&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;sticker&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;users&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:aaron&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;login_as&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;sticker&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;flashback&lt;/span&gt;
  &lt;span class='n'&gt;post&lt;/span&gt; &lt;span class='ss'&gt;:create&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:user_id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:sticky&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='ss'&gt;:message&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;blah&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='n'&gt;assert_match&lt;/span&gt;&lt;span class='sr'&gt; /Problems .+ Sticky/&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flashed&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:error&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;#8217;s what the important part of create looks like in the controller:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;StickiesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;create&lt;/span&gt;
    &lt;span class='c1'&gt;# ...&lt;/span&gt;
  &lt;span class='k'&gt;rescue&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;RecordInvalid&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;e&lt;/span&gt;
    &lt;span class='n'&gt;flash&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;now&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:error&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Problems erupted while saving the Sticky&amp;quot;&lt;/span&gt;
    &lt;span class='n'&gt;render&lt;/span&gt; &lt;span class='ss'&gt;:action&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;new&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;Simple and easy:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://glomp.rubyforge.org/flashback'&gt;Documentation&lt;/a&gt; is served from &lt;a href='http://rubyforge.org/projects/glomp'&gt;RubyForge&lt;/a&gt;, just like the plugin itself.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Assert Session</title>
   <link href="http://gusg.us/code/ruby/assert-session-extending-assert-request.html"/>
   <updated>2008-01-08T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/assert-session-extending-assert-request</id>
   <content type="html">&lt;p&gt;I was coding along in Rails with security in mind using the simple &lt;a href='http://validaterequest.rubyforge.org/'&gt;Assert Request&lt;/a&gt; plugin from &lt;a href='http://workingwithrails.com/person/5938-scott-woods'&gt;Scott A Woods&lt;/a&gt; in my controllers and ran into a spot where I wanted to require the presence of a session variable before allowing the rest of an action to execute. The specific motivation was conceived when coding a controller for an invitation mechanism. Normally, a user invites another user to a system, the invited user comes to the system with their invite-code (probably from a link in an email), completes some form (let&amp;#8217;s call it invite-accept), and then submits the final request (invite-update).&lt;/p&gt;

&lt;p&gt;What I didn&amp;#8217;t want was an easy way for a user to be able to by-pass the invite-accept and go straight to invite-update. To prevent this, I wanted the invite-code to be available to invite-update, but not via a parameter. The quickest and safest way I could think was to require that it be in the session, which would theoretically force the user to first visit invite-accept. This way, only invited people can accept invites and they must go through invite-accept.&lt;/p&gt;

&lt;p&gt;I also really liked the convention of using &lt;code&gt;assert_request&lt;/code&gt; at the head of each of my actions (I even implemented an &lt;code&gt;assert_request_has_no_params&lt;/code&gt; helper for most of them) and I didn&amp;#8217;t want to break from it to do a:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;some_action&lt;/span&gt;
  &lt;span class='k'&gt;raise&lt;/span&gt; &lt;span class='no'&gt;Exception&lt;/span&gt; &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
  &lt;span class='c1'&gt;# ...&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='interpretation'&gt;Interpretation&lt;/h2&gt;

&lt;p&gt;So, I wrote an extension to &lt;code&gt;AssertRequest&lt;/code&gt; called - oddly enough - &lt;code&gt;AssertSession&lt;/code&gt;. It&amp;#8217;s not complex and looks very similar to existing &lt;code&gt;AssertRequest&lt;/code&gt; code. It currently supports two directives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:must_have&lt;/code&gt; - Requires the existence of declared session variable(s) or an error is raised&lt;/li&gt;

&lt;li&gt;&lt;code&gt;:may_have&lt;/code&gt; - Allows for the existence of declared session variable(s)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following code example shows how one might require the existence of three session variables for the given request: &lt;code&gt;:baz&lt;/code&gt;, &lt;code&gt;:bum&lt;/code&gt;, and &lt;code&gt;:bar&lt;/code&gt;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;FooController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;bar&lt;/span&gt;
    &lt;span class='n'&gt;assert_session&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;rule&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;rule&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt; &lt;span class='ss'&gt;:baz&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:bum&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:bar&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If any one of the session variables does not exist in the session at the time the request is processed, a &lt;code&gt;AssertRequest::RequestError&lt;/code&gt; exception is raised with a meaningful error message; like:&lt;/p&gt;

&lt;p&gt;What if you only wanted to require &lt;code&gt;:baz&lt;/code&gt;, but you wanted to allow for &lt;code&gt;:boo&lt;/code&gt; and &lt;code&gt;:bar&lt;/code&gt;?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;FooController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;bar&lt;/span&gt;
    &lt;span class='n'&gt;assert_session&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;rule&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='n'&gt;rule&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt; &lt;span class='ss'&gt;:baz&lt;/span&gt;
      &lt;span class='n'&gt;rule&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;may_have&lt;/span&gt; &lt;span class='ss'&gt;:boo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:bar&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For this example, an error will only be thrown if &lt;code&gt;:baz&lt;/code&gt; is not defined at the time of the request. &lt;code&gt;:boo&lt;/code&gt; and &lt;code&gt;:bar&lt;/code&gt; may or may not be defined. This was useful for me to allow session variables that might have been stored during login actions, like a &lt;code&gt;return_to&lt;/code&gt; &lt;em&gt;(though, in this case, it might be more prudent to allow a global ignore style declaration)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In addition, any variable found in the session that is not declared as a &lt;code&gt;must_have&lt;/code&gt; or a &lt;code&gt;may_have&lt;/code&gt; is considered malicious and a &lt;code&gt;AssertRequest::RequestError&lt;/code&gt; exception is raised with a meaningful error message. For instance, given either of the above examples, the request will be halted and an error with the following message raised if a session variable is defined named &lt;code&gt;:toothrot&lt;/code&gt;.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='s2'&gt;&amp;quot;:toothrot not expected to be in session&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;By default, &lt;code&gt;AssertSession&lt;/code&gt; will ignore the variable named &lt;code&gt;flash&lt;/code&gt; in the session.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AssertSession&lt;/code&gt; works right along &lt;code&gt;AssertRequest&lt;/code&gt;, but cannot be called from within an &lt;code&gt;assert_request&lt;/code&gt; block.&lt;/p&gt;

&lt;h2 id='application'&gt;Application&lt;/h2&gt;

&lt;p&gt;Back to the original motivation; the invitations controller. After having implemented &lt;code&gt;assert_session&lt;/code&gt;, I was able to use it in the controller like so:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;InvitesController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='c1'&gt;# ...&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;accept&lt;/span&gt;
    &lt;span class='n'&gt;assert_request&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt; &lt;span class='ss'&gt;:invite_code&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='vi'&gt;@user&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find_invited&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
  &lt;span class='k'&gt;rescue&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;RecordNotFound&lt;/span&gt;
    &lt;span class='n'&gt;bad_request&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;The invite code you provided is invalid.&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;update&lt;/span&gt;
    &lt;span class='n'&gt;assert_session&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:invite_code&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt; &lt;span class='n'&gt;s&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;may_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:return_to&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='n'&gt;assert_post&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='n'&gt;r&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:user&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;u&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='n'&gt;u&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;must_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:password&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='ss'&gt;:password_confirmation&lt;/span&gt;&lt;span class='p'&gt;)}&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='c1'&gt;# ...&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;:return_to&lt;/code&gt; should really only be present if you&amp;#8217;ve ever tried to login, but since I do a lot of playing in the interface, I would routinely hit the problem where &lt;code&gt;:return_to&lt;/code&gt; existed and I didn&amp;#8217;t really feel like clearing my sessions (&lt;code&gt;:return_to&lt;/code&gt; comes with &lt;code&gt;acts_as_authenticated&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;assert_post&lt;/code&gt; is another helper I wrote which simply does an &lt;code&gt;assert_request&lt;/code&gt;, requires the method to be a POST, and then yields. Like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;assert_post&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;block&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='n'&gt;assert_request&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;rules&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='n'&gt;rules&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;method&lt;/span&gt; &lt;span class='ss'&gt;:post&lt;/span&gt;
    &lt;span class='k'&gt;yield&lt;/span&gt; &lt;span class='n'&gt;rules&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A cooler approach would be if &lt;code&gt;assert_request&lt;/code&gt; itself was modified to accept the required HTTP method as an argument. An example of use would be:&lt;/p&gt;

&lt;p&gt;Liquid error: stack level too deep&lt;/p&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;First, install the &lt;code&gt;AssertRequest&lt;/code&gt; plugin.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;ruby&lt;/span&gt; &lt;span class='n'&gt;script&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;plugin&lt;/span&gt; &lt;span class='n'&gt;install&lt;/span&gt; &lt;span class='n'&gt;svn&lt;/span&gt;&lt;span class='ss'&gt;:/&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;rubyforge&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;org&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;var&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;svn&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;validaterequest&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;plugins&lt;/span&gt;&lt;span class='o'&gt;/&lt;/span&gt;&lt;span class='n'&gt;assert_request&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Second, create a file using the code below in your Rails application and require it in your &lt;code&gt;environment.rb&lt;/code&gt; file. When Scott Woods accepts the patch, you can simply install/update the plugin you have installed.&lt;/p&gt;

&lt;h2 id='code'&gt;Code&lt;/h2&gt;

&lt;p&gt;Until Scott Woods adds the code into the plugin, the code only exists here.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Glomp&lt;/span&gt; &lt;span class='c1'&gt;#:nodoc:&lt;/span&gt;
  &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;AssertRequest&lt;/span&gt; &lt;span class='c1'&gt;#:nodoc:&lt;/span&gt;
    &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;PublicMethods&lt;/span&gt; &lt;span class='c1'&gt;#:nodoc:&lt;/span&gt;
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;assert_session&lt;/span&gt;
        &lt;span class='n'&gt;rules&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;SessionRules&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
        &lt;span class='k'&gt;yield&lt;/span&gt; &lt;span class='n'&gt;rules&lt;/span&gt;
        &lt;span class='n'&gt;rules&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;validate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# PublicMethods&lt;/span&gt;
  
    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;SessionRules&lt;/span&gt;
      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;
        &lt;span class='vi'&gt;@required&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;
        &lt;span class='vi'&gt;@ignore_vars&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;flash&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;

      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;must_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='vi'&gt;@required&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;concat&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flatten!&lt;/span&gt;
        &lt;span class='nb'&gt;self&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;

      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;may_have&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;*&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='vi'&gt;@ignore_vars&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;concat&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;args&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;flatten!&lt;/span&gt;
        &lt;span class='nb'&gt;self&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;

      &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;validate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='n'&gt;cats&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='ss'&gt;:expected&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:unexpected&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:matched&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
        &lt;span class='n'&gt;session&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;data&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='n'&gt;v&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
          &lt;span class='n'&gt;cat&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@required&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;index&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;k&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;v&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='ss'&gt;:expected&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='ss'&gt;:matched&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='ss'&gt;:unexpected&lt;/span&gt;
          &lt;span class='n'&gt;cats&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;cat&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;k&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
        &lt;span class='n'&gt;cats&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:expected&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='vi'&gt;@required&lt;/span&gt; &lt;span class='o'&gt;-&lt;/span&gt; &lt;span class='n'&gt;cats&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:matched&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='n'&gt;cats&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:expected&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;empty?&lt;/span&gt;
          &lt;span class='k'&gt;raise&lt;/span&gt; &lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;AssertRequest&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;RequestError&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
            &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;cats&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:expected&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;to_sentence&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; expected to be in session&amp;quot;&lt;/span&gt;
        &lt;span class='k'&gt;elsif&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;cats&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:unexpected&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;-=&lt;/span&gt; &lt;span class='vi'&gt;@ignore_vars&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;empty?&lt;/span&gt;
          &lt;span class='k'&gt;raise&lt;/span&gt; &lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;AssertRequest&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;RequestError&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
            &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;cats&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:unexpected&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;to_sentence&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; not expected to be in session&amp;quot;&lt;/span&gt;
        &lt;span class='k'&gt;end&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# AssertRequest&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# Glomp&lt;/span&gt;

&lt;span class='no'&gt;ActionController&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:include&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Glomp&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;AssertRequest&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;PublicMethods&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Tests are available upon request.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Full on Errors</title>
   <link href="http://gusg.us/code/ruby/full-on-errors.html"/>
   <updated>2007-12-21T00:00:00-06:00</updated>
   <id>http://gusg.us/code/ruby/full-on-errors</id>
   <content type="html">&lt;p&gt;ActiveRecord&amp;#8217;s &lt;code&gt;full\_messages&lt;/code&gt; method is a useful one for many reasons. I like using it as a message for tests that fail for strange reasons. I like it for displaying error messages in a view, which is simpler than modifying how &lt;code&gt;error\_messages\_for&lt;/code&gt; displays. However, I have always found it annoying that I cannot ask an &lt;code&gt;ActiveRecord&lt;/code&gt; object for the full-messages on a specific attribute &amp;#8230; until now.&lt;/p&gt;

&lt;p&gt;To remedy this, I wrote the &lt;strong&gt;&lt;code&gt;full\_on\_errors&lt;/code&gt;&lt;/strong&gt; plugin which simply adds a &lt;code&gt;full\_on&lt;/code&gt; method to the &lt;code&gt;Errors&lt;/code&gt; class of an &lt;code&gt;ActiveRecord&lt;/code&gt; instance. It&amp;#8217;s use is simple; simply call &lt;code&gt;full_on&lt;/code&gt; and pass the attribute for which you would like the full messages for.&lt;/p&gt;

&lt;h2 id='example'&gt;Example&lt;/h2&gt;

&lt;p&gt;In fact, it&amp;#8217;s so simple that examples are coming in the third paragraph. Let&amp;#8217;s say you have a User model that looks like the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;User&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
  &lt;span class='n'&gt;validates_presence_of&lt;/span&gt; &lt;span class='ss'&gt;:name&lt;/span&gt;
  &lt;span class='n'&gt;validates_presence_of&lt;/span&gt; &lt;span class='ss'&gt;:email&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Ignoring the fact that you could one-line the validation, if you were to validate a new instance of User that does not provide &lt;code&gt;name&lt;/code&gt; or &lt;code&gt;email&lt;/code&gt;, you would receive two error messages. With &lt;em&gt;&lt;code&gt;full\_messages&lt;/code&gt;&lt;/em&gt;, what would return would look like the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;user&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;valid?&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;errors&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;full_messages&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Name can&amp;#39;t be blank&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Email can&amp;#39;t be blank&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But, what if you wanted the full-messages for just the &lt;code&gt;name&lt;/code&gt; attribute? You could look for those errors that start with name; you could live with &lt;code&gt;user.errors.on(:name)&lt;/code&gt; returning an array of partial error message; or you could do the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;user&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;
&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;valid?&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;errors&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;full_on&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Name can&amp;#39;t be blank&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Step 1:&lt;/em&gt; install the Rails plugin:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='text'&gt;$RAILS_ROOT&amp;gt; ./script/plugin install \
  http://glomp.rubyforge.org/svn/plugins/full_on_errors
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Step 2:&lt;/em&gt; Start using it&lt;/p&gt;

&lt;h2 id='code'&gt;Code&lt;/h2&gt;

&lt;p&gt;The code is extremely simple and is - oddly enough - based on &lt;code&gt;Errors.full\_messages&lt;/code&gt;. I have simplified the &lt;code&gt;full\_messages&lt;/code&gt; code to focus on one attribute, to do less, and to look better (according to Gus Aesthetics):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Glomp&lt;/span&gt; &lt;span class='c1'&gt;#:nodoc:&lt;/span&gt;
  &lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;FullOnErrors&lt;/span&gt; &lt;span class='c1'&gt;#:nodoc:&lt;/span&gt;
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;full_on&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;attr_name&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='kp'&gt;attr&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;attr_name&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_s&lt;/span&gt;
      &lt;span class='n'&gt;errs&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;on&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_a&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='n'&gt;errs&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='kp'&gt;attr&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;base&amp;#39;&lt;/span&gt;
      &lt;span class='n'&gt;human_name&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@base&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;class&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;human_attribute_name&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='n'&gt;errs&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;map&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;msg&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;human_name&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;msg&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# FullOnErrors&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt; &lt;span class='c1'&gt;# Glomp&lt;/span&gt;

&lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Errors&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;send&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:include&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;Glomp&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;FullOnErrors&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For comparison&amp;#8217;s sake, here is the &lt;code&gt;full\_messages&lt;/code&gt; code from the Errors class:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# Returns all the full error messages in an array.&lt;/span&gt;
&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;full_messages&lt;/span&gt;
  &lt;span class='n'&gt;full_messages&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;

  &lt;span class='vi'&gt;@errors&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each_key&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='kp'&gt;attr&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='vi'&gt;@errors&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='kp'&gt;attr&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;msg&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='k'&gt;next&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;msg&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;nil?&lt;/span&gt;

      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='kp'&gt;attr&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;base&amp;quot;&lt;/span&gt;
        &lt;span class='n'&gt;full_messages&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='n'&gt;msg&lt;/span&gt;
      &lt;span class='k'&gt;else&lt;/span&gt;
        &lt;span class='n'&gt;full_messages&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='vi'&gt;@base&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;class&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;human_attribute_name&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;attr&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='n'&gt;msg&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='n'&gt;full_messages&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Password Sophistication</title>
   <link href="http://gusg.us/code/password-sophistication.html"/>
   <updated>2007-11-12T00:00:00-06:00</updated>
   <id>http://gusg.us/code/password-sophistication</id>
   <content type="html">&lt;p&gt;I went looking for one of those JavaScript, password strength meter things like you see on some signup pages (see &lt;a href='https://www.google.com/accounts/NewAccount'&gt;Google Signup&lt;/a&gt;) which attempt to coerce you into believing the security of the password you are about to enroll with. I wanted to use it for a new site I am working on and I do think there are merits to forcing users to make a decision between accepting a &lt;em&gt;Secure&lt;/em&gt; versus an &lt;em&gt;Insecure&lt;/em&gt; password.&lt;/p&gt;

&lt;p&gt;While I am a developer and I know JavaScript, I didn&amp;#8217;t feel like implementing the &lt;em&gt;strength&lt;/em&gt; algorithm myself; so I went in search of an existing solution. In the course of the search for the right solution(s), I happened upon two learnings:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The code for implementation was not &lt;em&gt;purty&lt;/em&gt;; to be addressed in Findings&lt;/li&gt;

&lt;li&gt;I became hesitant to call the whole process a &amp;#8220;strength&amp;#8221; test&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id='sophistication'&gt;Sophistication&lt;/h2&gt;

&lt;p&gt;Calling the algorithm a &lt;em&gt;security strength&lt;/em&gt; test really violated by sensibility. Passwords are broken all the time and considering that most of the client-side testing algorithms don&amp;#8217;t even use a dictionary lookup, I really believe that no assurance of strength can be given about a user&amp;#8217;s password when using the majority of these algorithms.&lt;/p&gt;

&lt;p&gt;Instead, the test or score reflects the &lt;strong&gt;Sophistication&lt;/strong&gt; of the user&amp;#8217;s password. Most of the algorithms look for the following patterns:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Password length; hopefully over 8&lt;/li&gt;

&lt;li&gt;At least one lower-case letter&lt;/li&gt;

&lt;li&gt;At least one upper-case letter&lt;/li&gt;

&lt;li&gt;At least one digit&lt;/li&gt;

&lt;li&gt;A special character like {!,#,$,%,&amp;#8230;}&lt;/li&gt;

&lt;li&gt;Combinations of upper- and lower-case letters&lt;/li&gt;

&lt;li&gt;Combinations of letters and digits&lt;/li&gt;

&lt;li&gt;Combinations of letters, digits, and special characters&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the occurrences of letters, digits, and special characters, scores go up as frequency increases; with a cap.&lt;/p&gt;

&lt;p&gt;To this end, it is my belief that only the sophistication of the user&amp;#8217;s password, in relation to the known patterns of insecurity, is at question.&lt;/p&gt;

&lt;p&gt;So, my proposal is to not use the classifications of &lt;em&gt;Insecure&lt;/em&gt;, &lt;em&gt;Mediocre&lt;/em&gt;, &lt;em&gt;Secure&lt;/em&gt;, and &lt;em&gt;Very Secure&lt;/em&gt;, but to instead use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Risky&lt;/li&gt;

&lt;li&gt;Weak&lt;/li&gt;

&lt;li&gt;Smart&lt;/li&gt;

&lt;li&gt;Sophisticated&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of course, it would be funnier to use something like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;So &amp;#8230; you really don&amp;#8217;t care about security?&lt;/li&gt;

&lt;li&gt;Is that really your password?&lt;/li&gt;

&lt;li&gt;Getting warmer&lt;/li&gt;

&lt;li&gt;Sweet!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But, my wife does not like those so I won&amp;#8217;t be using them.&lt;/p&gt;

&lt;h2 id='findings'&gt;Findings&lt;/h2&gt;

&lt;p&gt;A quick question to &lt;a href='http://www.google.com/search?q=javascript+password+strength+meter'&gt;the Google&lt;/a&gt; produced the following two links at some point:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href='http://www.geekwisdom.com/dyn/passwdmeter'&gt;Geek Wisdom&lt;/a&gt;: which I used for the Scoring algorithm&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.codeandcoffee.com/2007/06/27/how-to-make-a-password-strength-meter-like-google/'&gt;Code &amp;amp; Coffee&lt;/a&gt;: which I used for the Interface Design&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id='scoring'&gt;Scoring&lt;/h3&gt;

&lt;p&gt;I chose the scoring algorithm from Geek Wisdom because it was actually very paranoid. None of the passwords I use or my friends use on regular basis, and which are fairly sophisticated, even made it into the &lt;em&gt;secure&lt;/em&gt; classification.&lt;/p&gt;

&lt;p&gt;The code was actually kind of ugly; in that it seemed some cycles were getting wasted and the regular expressions needed improving. The author of the original code would agree to as much; and the comments on the post verify as much.&lt;/p&gt;

&lt;h3 id='design'&gt;Design&lt;/h3&gt;

&lt;p&gt;The design code from Code &amp;amp; Coffee was also useful and &lt;a href='http://www.codeandcoffee.com/wp-content/uploads/pwd_strength.js'&gt;simple enough&lt;/a&gt;. It came with a built in scoring algorithm, which was not paranoid enough.&lt;/p&gt;

&lt;p&gt;I liked how simple the solution to the meter was, but I did not like that the colors were essentially hard-coded in. I also don&amp;#8217;t like that the &lt;em&gt;strength&lt;/em&gt; classifications (like Secure, Insecure, etc.) are hard-coded, but this is a less trivial solution to program and probably not worth the effort.&lt;/p&gt;

&lt;h2 id='implementation'&gt;Implementation&lt;/h2&gt;

&lt;p&gt;My initial implementation was essentially the implementation from Code &amp;amp; Coffee with the algorithm of Geek Wisdom; but what I really wanted was a nice OO thing. I also wanted to be able to define colors in CSS.&lt;/p&gt;

&lt;p&gt;My final JavaScript looks like the following (passwd.js):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;PasswordSophistication&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;Class&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;create&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
&lt;span class='nb'&gt;Object&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;extend&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;PasswordSophistication&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;prototype&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;initialize&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwordFieldId&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fieldIdPrefix&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;passwordField&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;document&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getElementById&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwordFieldId&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;barElement&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;document&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getElementById&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fieldIdPrefix&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;_bar&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;textElement&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;document&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getElementById&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;fieldIdPrefix&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;_text&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;

    &lt;span class='c'&gt;// rate = [minimum-to-meet, text-to-display, css-class]&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;rates&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;
      &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;90&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Sophisticated&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;sophisticated&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;60&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Smart&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;smart&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;30&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Weak&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;weak&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;
      &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Risky&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;risky&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;]];&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;defaultRate&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Password Sophistication&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;risky&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;

  &lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;passwordField&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;value&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;

  &lt;span class='c'&gt;// Score the password&lt;/span&gt;
  &lt;span class='nx'&gt;score&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
    &lt;span class='nx'&gt;passwd&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;
    &lt;span class='c'&gt;// Length&lt;/span&gt;
    &lt;span class='nx'&gt;len&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;len&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;7&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;18&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;len&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;len&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='c'&gt;// Letters&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/[a-z]/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/[A-Z]/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='c'&gt;// Numbers&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/[0-9]/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/([0-9].*){3}/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='c'&gt;// 1 or 2 Special characters&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/[,!@#$%^&amp;amp;*?_~=+-]/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/([,!@#$%^&amp;amp;*?_~=+-].*){2}/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='c'&gt;// Combinations&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/([a-z].*[A-Z])|([A-Z].*[a-z])/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/([0-9].*[a-zA-Z]|[a-zA-Z].*[0-9])/&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='nx'&gt;rex&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='sr'&gt;/([a-zA-Z0-9].*[!,@#$%^&amp;amp;*?_~=+-]|[!,@#$%^&amp;amp;*?_~=+-].*[a-zA-Z0-9])/&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;passwd&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;rex&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+=&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
  
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='c'&gt;// Because score maxes at 50&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt;

  &lt;span class='c'&gt;// Update the view&lt;/span&gt;
  &lt;span class='nx'&gt;update&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='k'&gt;function&lt;/span&gt; &lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;barElement&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;textElement&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;return&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;

    &lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt;&lt;span class='p'&gt;();&lt;/span&gt;

    &lt;span class='nx'&gt;rate&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;rates&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;length&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class='nx'&gt;rate&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt; &lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='o'&gt;++&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;rates&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;][&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;])&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;rate&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;rates&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;i&lt;/span&gt;&lt;span class='p'&gt;];}&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;rate&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='kc'&gt;null&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;rate&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;defaultRate&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
 
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;barElement&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;style&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;width&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;score&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;%&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;;&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;barElement&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;className&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;rate&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
    &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;textElement&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;innerHTML&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;rate&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='p'&gt;}&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Following is an excerpt of how to use it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;script &lt;/span&gt;&lt;span class='na'&gt;src=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;/javascripts/passwd.js&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;link&lt;/span&gt; &lt;span class='na'&gt;href=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;/stylesheets/passwd.css&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;media=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;screen&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;rel=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;Stylesheet&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;class=&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;label&amp;#39;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&amp;lt;label&lt;/span&gt; &lt;span class='na'&gt;for=&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Password&lt;span class='nt'&gt;&amp;lt;/label&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class='nt'&gt;&amp;lt;input&lt;/span&gt; &lt;span class='na'&gt;id=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;user_password&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;name=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;user[password]&amp;quot;&lt;/span&gt;
      &lt;span class='na'&gt;onkeyup=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;passwdMeter.update();&amp;quot;&lt;/span&gt;
      &lt;span class='na'&gt;size=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;30&amp;quot;&lt;/span&gt; &lt;span class='na'&gt;type=&lt;/span&gt;&lt;span class='s'&gt;&amp;quot;password&amp;quot;&lt;/span&gt; &lt;span class='nt'&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;id=&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;passwd_text&amp;#39;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;Password Sophistication&lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class='nt'&gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;id=&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;passwd_meter&amp;#39;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&amp;lt;div&lt;/span&gt; &lt;span class='na'&gt;id=&lt;/span&gt;&lt;span class='s'&gt;&amp;#39;passwd_bar&amp;#39;&lt;/span&gt;&lt;span class='nt'&gt;&amp;gt;&lt;/span&gt;&lt;span class='ni'&gt;&amp;amp;nbsp;&lt;/span&gt;&lt;span class='nt'&gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class='nx'&gt;passwdMeter&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;new&lt;/span&gt; &lt;span class='nx'&gt;PasswordSophistication&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;user_password&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;passwd&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So, the important part is the initialization of the meter via the PasswordSophistication object. The PasswordSophistication constructor expects two DOM Id&amp;#8217;s:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, is the Id pointing to the password field; &amp;#8216;user_password&amp;#8217; in this case&lt;/li&gt;

&lt;li&gt;Second, is the prefix of the DOM Id that represent the meter &lt;strong&gt;bar&lt;/strong&gt; and &lt;strong&gt;text&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The use of the prefix for the fields is the same implementation as that originally defined in the Code &amp;amp; Coffee article.&lt;/p&gt;

&lt;p&gt;The other important piece is the &lt;strong&gt;onkeyup&lt;/strong&gt; defined in the password field, which calls &lt;em&gt;update()&lt;/em&gt; on the password meter object.&lt;/p&gt;

&lt;p&gt;Now, colors come in via CSS (passwd.css):&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='css'&gt;&lt;span class='nf'&gt;#passwd_text&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;font-size&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;70%&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;#777&lt;/span&gt;&lt;span class='p'&gt;;}&lt;/span&gt;
&lt;span class='nf'&gt;#passwd_meter&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;.5ex&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt; &lt;span class='k'&gt;border&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;1px&lt;/span&gt; &lt;span class='k'&gt;solid&lt;/span&gt; &lt;span class='m'&gt;#ddd&lt;/span&gt;&lt;span class='p'&gt;;}&lt;/span&gt;
&lt;span class='nf'&gt;#passwd_bar&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;height&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;.5ex&lt;/span&gt;&lt;span class='p'&gt;;}&lt;/span&gt;
&lt;span class='nf'&gt;#passwd_bar&lt;/span&gt;&lt;span class='nc'&gt;.sophisticated&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nb'&gt;green&lt;/span&gt;&lt;span class='p'&gt;;}&lt;/span&gt;
&lt;span class='nf'&gt;#passwd_bar&lt;/span&gt;&lt;span class='nc'&gt;.smart&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='m'&gt;#a0ff01&lt;/span&gt;&lt;span class='p'&gt;;}&lt;/span&gt;
&lt;span class='nf'&gt;#passwd_bar&lt;/span&gt;&lt;span class='nc'&gt;.weak&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nb'&gt;orange&lt;/span&gt;&lt;span class='p'&gt;;}&lt;/span&gt;
&lt;span class='nf'&gt;#passwd_bar&lt;/span&gt;&lt;span class='nc'&gt;.risky&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='k'&gt;background-color&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='nb'&gt;red&lt;/span&gt;&lt;span class='p'&gt;;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That&amp;#8217;s pretty simple. Here&amp;#8217;s what it looks like with my &lt;strong&gt;smart&lt;/strong&gt; password:&lt;/p&gt;
&lt;img src='/images/articles/code/smart-passwd.png' /&gt;
&lt;h2 id='future_improvements'&gt;Future Improvements&lt;/h2&gt;

&lt;p&gt;There are lots of things that could improve the JavaScript. The most important are in the scoring algorithm, but the question is &lt;em&gt;&amp;#8220;What value is gained by doing so?&amp;#8221;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well, if someone has a good answer, here is my list:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Move the scoring rules into an ordered list of lambda functions that each accept the password and return an incremental score. If this was done, the score() method would be nothing more than an iterator that sums the scores of the lambda functions.&lt;/li&gt;

&lt;li&gt;Make the rates array a set of Objects that methods can be called on; like minScore, cssClass, and title.&lt;/li&gt;

&lt;li&gt;Provide a mechanism to allow the classification titles (ie Smart, Weak, etc.) and the CSS classes to be defined outside the PasswordSophistication prototype.&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 
</feed>