<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Live &amp; Code</title>
	
	<link>http://www.liveandcode.com</link>
	<description>Enrico on programming, living, and everything in between</description>
	<lastBuildDate>Tue, 23 Feb 2010 04:11:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/LiveAndCode" /><feedburner:info uri="liveandcode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Why I curse the TTC</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/bRwrTwySyrw/</link>
		<comments>http://www.liveandcode.com/2010/02/22/why-i-curse-the-ttc/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 03:49:49 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[commuting]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[Toronto]]></category>
		<category><![CDATA[TTC]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=380</guid>
		<description><![CDATA[It&#8217;s a quarter past 9 in the evening. I&#8217;ve just arrived from my office, which I departed from at not too bad a time: 6 PM. My commute on the TTC subway and bus from work to home, which typically takes an hour and a half, has taken me three hours. For that amount of [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a quarter past 9 in the evening. I&#8217;ve just arrived from my office, which I departed from at not too bad a time: 6 PM. My commute on the TTC subway and bus from work to home, which typically takes an hour and a half, has taken me <em>three hours</em>. For that amount of transit time, I probably could&#8217;ve paid my good friend <a title="maplealmond on Twitter" href="http://twitter.com/maplealmond">maplealmond</a> a visit in Kitchener. But I don&#8217;t live in Kitchener. I live near Finch and Islington.</p>
<p>My subway ride was smooth as usual. Having left the office later, the subway cars were not as crowded and almost halfway through the trip I managed to snag a seat and sit comfortably for the rest of the stops leading up to the north end of the Yonge line, Finch station.</p>
<p>This is where the fun begins.</p>
<p><a href="http://www.liveandcode.com/wp-content/uploads/2010/02/68545497.jpg"><img class="aligncenter size-full wp-image-383" title="Crowd at Finch Station" src="http://www.liveandcode.com/wp-content/uploads/2010/02/68545497.jpg" alt="A large crowd waits for 36 buses at Finch Station on the Yonge line" width="600" height="400" /></a></p>
<p><span id="more-380"></span></p>
<p>I reach the top of the three sets of stairs that lead from the subway platform to the bus platform. Then I move through a set of double doors to my left leading outside. The picture above fails to show the full magnitude of the crowd of people that I had to squeeze through to get to the location from which I shot it. The two lines of people that usually form for the 36 Finch West buses both curve in the same direction and run parallel to each other on the other side of the platform.</p>
<p>At this point, I know I&#8217;m in for a long wait in the cold and I&#8217;m visibly anxious. I watch all the buses that pass by.</p>
<p>Out of service. Out of service. 60. Another 60. 36C (<em>to Jane, not far enough for me</em>). Another 36C. A 36D (<em>Weston, still not quite far enough</em>). Out of service sign that switches to DETOUR ON ROUTE (<em>wait, what?</em>). Another 60&#8230;</p>
<p>As the 36&#8217;s stop to pick up people, I start to move closer and closer to the front of the line. But my bus is still to arrive. About an hour passes. I make fists with my hands to keep them a bit warmer. My feet hurt I am shivering. I continue to wait, wondering if maybe there was a detour on Finch West causing delays in getting buses back to the station.</p>
<p>Finally, a 36B. This one will go all the way down to Humberwood, well past where I need to get off. I&#8217;m close to the back door and desperate to get out of the cold. As we file onto the bus, I feel an unpleasant sensation between my shoulder blades: I&#8217;m being pushed from behind. Another passenger turns to yell at the man behind her, demanding to know why he&#8217;s pushing her. Clearly, the people behind us are as desperate to get on the bus as we are and considerably less polite about it.</p>
<p>The bus is packed as tight as a sardine can. The driver tells riders at the front door that he has no more room and that another bus is behind him; he doesn&#8217;t know if it is another B. The back door is particularly crowded. The riders there exit the bus and re-enter, playing a precarious game of human Tetris (no, not <em><a title="YouTube - Human Tetris" href="http://www.youtube.com/watch?v=Ll2kajMH2u0">that</a></em> human Tetris) against the two bars that trigger the door to open at stops. The driver tells people to try entering via the back door. Each time he does, the passengers near the back door groan.</p>
<p>We pass by the major stops: Dufferin, Bathurst. The bus is still roughly as packed as it began.</p>
<p>At Keele, a person further to the front squeezes past me to get to the back door. As he passes by, the messenger bag that is hanging on my right shoulder is pushed behind me and lifted way up. Finally, he manages to break through and exit the bus.</p>
<p>Not until Weston do enough people clear out to give me some space to breathe. There are still no seats however; I&#8217;ve been standing the whole time.</p>
<p>Now I&#8217;m home, quite irritated and wondering why my usual commute had suddenly doubled in length. TTC&#8217;s <a title="Official TTC Tweets (TTCnotices)" href="http://twitter.com/TTCnotices">official Twitter feed for service notices</a> says nothing about it. It reminded me of a customer service tip that might be useful to the TTC: <em>perception matters</em>.</p>
<p>Even if you&#8217;re doing the best you can, if that&#8217;s not what it looks like to your customers, you have lost them. That&#8217;s why the photo of the sleeping fare collector caused such a stir in the community. We now pay more than ever for each ride, including Metropass holders, and we want to see the return on that investment.</p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/bRwrTwySyrw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2010/02/22/why-i-curse-the-ttc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2010/02/22/why-i-curse-the-ttc/</feedburner:origLink></item>
		<item>
		<title>Writing is Human Persistence</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/EbQKiRRfC5U/</link>
		<comments>http://www.liveandcode.com/2010/01/29/writing-is-human-persistence/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 00:51:07 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Personal Development]]></category>
		<category><![CDATA[creativity]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[The Human Computer]]></category>
		<category><![CDATA[writing]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=358</guid>
		<description><![CDATA[One of many tips for improving one&#8217;s creativity is to keep a notebook available to write down ideas as you get them. The rationale behind this is that if you don&#8217;t have something to record your idea in the moment you get it, you might forget it by the time you do have something to [...]]]></description>
			<content:encoded><![CDATA[<p>One of many tips for improving one&#8217;s creativity is to keep a notebook available to write down ideas as you get them. The rationale behind this is that if you don&#8217;t have something to record your idea in the moment you get it, you might forget it by the time you do have something to write it down on. It occurs to me that this might be another sense in which we are similar to computers.</p>
<p><span id="more-358"></span><br />
<a href="http://en.wikipedia.org/wiki/Random-access_memory" title="Random-access memory - Wikipedia">RAM</a> holds the current information that a program is working with, but it doesn&#8217;t hold on to it forever. Once the program has exited, the RAM it was using is (ideally) reclaimed by the operating system for use by other programs. If a program needs to keep information for the next time it executes, it will get written to the hard drive or to another form of <em><a href="http://en.wikipedia.org/wiki/Persistence_(computer_science)" title="Persistence (computer science) - Wikipedia">persistence</a></em>.</p>
<p>I imagine short-term memory as being very similar to RAM. The thoughts are in your head, but they aren&#8217;t going to stay there forever. Even long-term memory is not entirely reliable; <a href="http://www.telegraph.co.uk/technology/3778272/The-perils-of-relying-on-memory-in-court.html" title="The perils of relying on memory in court - Telegraph.co.uk">the act of recalling something changes it slightly</a>. So if our memory isn&#8217;t the best place to keep ideas for later, where should we keep them? <strong>In writing.</strong></p>
<p>The act of reading words doesn&#8217;t change them. The letters which were printed may become illegible but they will never change. The information that those written words encode persists, and is the same every time you read it. The written word is how we have aggregated the collective information of our entire species with the accuracy and efficiency that we needed to make our social and technological advances.</p>
<p>One of my goals for 2010 is to write more things down and stop trying to keep so much in my head.</p>
<p>I&#8217;ll close this brief thought by quoting a <a href="http://www.petermichaud.com/essays/the-secret-about-writing-that-no-one-has-the-balls-to-tell-you/" title="The secret about writing that no one has the balls to tell you - Pete Michaud">blog post</a> I read recently about writing:</p>
<blockquote><p>
The amount of information our brains can fit into our short term memory at once isn’t a lot. If you never have thoughts that require notes, then all your thoughts are small or unoriginal enough to fit into your tiny short term memory.</p>
<p>Writing allows you to record your short term memory into a format that you can examine and reflect upon, so you can suss out what makes sense, and how it makes sense, and then expand on the original seed. When you expand your thought all the way into a piece of coherent writing, it becomes complete. It would have been impossible for you to have that size of a thought without writing–your brain just isn’t powerful enough.
</p></blockquote>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/EbQKiRRfC5U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2010/01/29/writing-is-human-persistence/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2010/01/29/writing-is-human-persistence/</feedburner:origLink></item>
		<item>
		<title>Take the Reins</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/-AwdhYKBKeM/</link>
		<comments>http://www.liveandcode.com/2010/01/15/take-the-reins/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 03:51:11 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Personal Development]]></category>
		<category><![CDATA[life lessons]]></category>
		<category><![CDATA[self esteem]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=342</guid>
		<description><![CDATA[A few days ago, Jon Crowley tweeted (and I retweeted) a piece of advice that I&#8217;ve lately found more and more relevant to my life and the lives of others around me:
It&#8217;s easy — comfortable, even! — to feel like you are stuck in a rut, a victim of circumstances that prevent you from being truly awesome, [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, <a href="http://attentionindustry.com/" title="Attention Industry">Jon Crowley</a> tweeted (and I retweeted) a piece of advice that I&#8217;ve lately found more and more relevant to my life and the lives of others around me:</p>
<div id="attachment_343" class="wp-caption aligncenter" style="width: 474px"><a href="http://www.liveandcode.com/wp-content/uploads/2010/01/joncrowley-key_to_failure.png"><img class="size-full wp-image-343 " title="Jon Crowley: The Key to Failure" src="http://www.liveandcode.com/wp-content/uploads/2010/01/joncrowley-key_to_failure.png" alt="" width="464" height="234" /></a><p class="wp-caption-text">@joncrowley: &quot;I&#39;m convinced that the key to failure is thinking of life as something that is done to you, rather than something you do.&quot;</p></div>
<p><span id="more-342"></span>It&#8217;s easy — comfortable, even! — to feel like you are stuck in a rut, a victim of circumstances that prevent you from being truly awesome, but it&#8217;s simply not true: y<em>ou are always in control</em>.</p>
<p>You can&#8217;t ensure the outcome of every endeavour you undertake, but you choose your actions, your reactions, your thoughts, and your words. Even though you command all of these things, you may still feel like you are burdened by obligation or paralyzed by fear.</p>
<p><strong>Take the reins.</strong> Steer your life in the direction of your desires. Work hard to achieve those things which are most important to you as you cut away those things which bring you down. Don&#8217;t let life just <em>happen</em> to you. Your life is finite and fleeting. Be present and engaged in every single moment and wring out every bit of joy and excitement that you can. Unless you have a very strong belief in life after death, this time which is steadily elapsing is all you&#8217;ve got. Even if you do have faith, why waste time?</p>
<p>That&#8217;s what I think anyway, but it&#8217;s <em>your</em> call.</p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/-AwdhYKBKeM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2010/01/15/take-the-reins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2010/01/15/take-the-reins/</feedburner:origLink></item>
		<item>
		<title>Context Switching</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/qGfdKOl6IJo/</link>
		<comments>http://www.liveandcode.com/2010/01/11/context-switching/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 02:57:37 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[The Human Computer]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=337</guid>
		<description><![CDATA[One of the reasons this blog is called &#8220;Live &#38; Code&#8221; is because Computer Science (and by extension programming) is one of the lenses through which I view the world. There are often parallels between the way we think and the way computers work. I don&#8217;t think that this is an accident; the term &#8220;computer&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>One of the reasons this blog is called &#8220;Live &amp; Code&#8221; is because Computer Science (and by extension programming) is one of the lenses through which I view the world. There are often parallels between the way we think and the way computers work. I don&#8217;t think that this is an accident; the term &#8220;computer&#8221; used to refer to a human being whose profession was computing values. These people would sit and work through algorithms to calculate values that would be used in scientific research.</p>
<p>One of these parallels between humans and computers is the way that we multitask. Computers only <em>seem</em> to multitask by switching between tasks rapidly, with the exception of new multi-core and multi-processor systems, which can run as many tasks in parallel as there are cores or processors. So it was interesting to read recently that <a title="Human multitasking - Wikipedia" href="http://en.wikipedia.org/wiki/Human_multitasking">the prevailing theory is that humans multitask in precisely the same way</a>!</p>
<p><span id="more-337"></span></p>
<p>Analogous to a multitasking CPU, current experimental psychology research shows that <a title="Dual-Task Interference in Simple Tasks: Data and Theory - Harold Pashler [PDF]" href="http://www.pashler.com/Articles/Pashler_PB1994.pdf">interference occurs</a> when we attempt to perform even simple tasks simultaneously. There are certain exceptions to this, particularly when one of the two tasks is stored in &#8220;muscle memory&#8221;, but this is because we can perform such tasks without even thinking about them. In many other cases, the effectiveness with which we perform the tasks is diminished when we are doing more than one task at the same time.</p>
<p>It is also common wisdom in IT that when somebody is deep in his/her work (commonly referred to as <em><a title="Flow (psychology) - Wikipedia" href="http://en.wikipedia.org/wiki/Flow_(psychology)">flow</a></em>), an interruption of even a few seconds can result in <em>15 minutes</em> of lost productivity. While I&#8217;ve never verified the actual number, I have often had trouble putting myself back on a task after being jolted out of it by a short interruption.</p>
<p>When a CPU switches tasks, it must perform a <em><a title="Context Switch - Wikipedia" href="http://en.wikipedia.org/wiki/Context_switch">context switch</a></em>. The current state of the program that is running on the computer, including the values stored in the registers, a reference to the next instruction to execute, and other housekeeping information are stored in memory (RAM). When the program comes back, the stored information is put back into its proper places so that the CPU can pick up where it left off. This is a fairly costly operation as the CPU cannot access RAM even a fraction as fast as it can access its registers. Of course, this means that when a CPU runs two programs simultaneously, it is less efficient at each than if it were concentrating entirely on one program or the other. Determining when to switch to a different program is therefore an incredibly important concern in the design of modern operating systems.</p>
<p>I&#8217;ve witnessed human &#8220;context switching&#8221; in a co-worker of mine. When I knock on her door to ask her a quick question about work that I&#8217;m doing for her, she asks me to give her a moment and looks to be deep in thought. She then asks me to repeat my question and answers it with surprising conciseness and accuracy. She has told me that she needs to switch from the mindset of what she&#8217;s currently working on to the mindset of what I&#8217;m asking her or she can&#8217;t answer properly.</p>
<p>This isn&#8217;t to say that multitasking is <em>bad</em>, but I am acutely aware that when I do multitask, I am not going to be able to perform each task as effectively as if I were focused entirely on one. Also, there are certain points at which it is easier or more natural to switch from doing one thing to doing another, particularly where I&#8217;ve accomplished a sub-goal in the task or where I&#8217;ve written down detailed notes on the current state of what I&#8217;m doing, which makes it easier to switch back to it later.</p>
<p>What do you think?</p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/qGfdKOl6IJo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2010/01/11/context-switching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2010/01/11/context-switching/</feedburner:origLink></item>
		<item>
		<title>Looking Forward to 2010</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/x8BlqofbXCM/</link>
		<comments>http://www.liveandcode.com/2009/12/31/looking-forward-to-2010/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 04:14:40 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[2010]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[new year]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=328</guid>
		<description><![CDATA[2009 has been a year of turbulent change for me.
Near the beginning of the year, I decided that I needed to switch gears in my career. I made a very dedicated push towards becoming a full-time Ruby developer, leaving my comfortable position as a J2EE web content management and identity management specialist. My leisure time [...]]]></description>
			<content:encoded><![CDATA[<p><strong>2009 has been a year of turbulent change for me.</strong></p>
<p>Near the beginning of the year, I decided that I needed to switch gears in my career. I made a very dedicated push towards becoming a full-time Ruby developer, leaving my comfortable position as a J2EE web content management and identity management specialist. My leisure time was consumed with sharpening my Ruby skills and learning new technologies. I made Rails Pub Nite a monthly ritual and networked like crazy on just about every networking site I could. I followed a number of job site feeds and sent out many cover letters and resumes.</p>
<p>Finally, my break came from a very unlikely source: <em>Facebook</em>. I posted to a Ruby on Rails group on Facebook to advertise my skills and experience and offer my services. This was seen by the Systems Manager at the <a href="http://www.csic-scci.ca/">Canadian Society of Immigration Consultants</a>, who asked me to send her my resume. I did so gladly and not too long after that I was asked in for an interview.</p>
<p><span id="more-328"></span></p>
<p>The project they needed me to work on was definitely very appealing, if a bit ambitious. They wanted to replace the monolithic pile of .NET that was currently doing an incredibly bad job of managing their records and processes and replace that with something leaner, meaner, and more attuned to their needs developed in-house using Ruby on Rails. This was my chance to gain experience working on a large Rails project from the ground up and to do so for a technologically progressive organization providing a valuable service to so many people all over the world.</p>
<p>That project is still on-going, and I recently accepted a permanent position with the Society. We hope to launch an initial release of the project early in the new year and I&#8217;m definitely bracing myself for a challenging job in 2010.</p>
<p>The professional networking I did then paid off in other ways as well. I previously <a href="http://www.liveandcode.com/2009/10/03/where-did-enric-go/">wrote</a> about how I helped a very good friend of mine land a job at <a href="http://www.postrank.com/">PostRank</a>. He moved to Kitchener/Waterloo while I moved back to North York, yet another of the changes that 2009 brought.</p>
<p>Finding myself back in Toronto after two years living in Mississauga, I quickly got to work making new friends and reconnecting with old. I&#8217;ve started participating in some <a href="http://meetup.com/">Meetup</a> groups related to my various interests, as well as events with <a href="http://genyto.com/">#GenYTO</a> and the <a href="http://freshbooks.com/">Freshbooks</a> crew. In just a few months, I&#8217;ve <a href="http://twitter.com/rlangdon">met</a> <a href="http://twitter.com/D_Hock">some</a> <a href="http://twitter.com/joncrowley">awesome</a> <a href="http://twitter.com/rochlatinsky">Torontonians</a> (I couldn&#8217;t possibly link to you all!).</p>
<p>So, at the end of 2009, I find myself in a new place — well, new in the sense that I haven&#8217;t been here in a couple of years — with a new job and new friends.</p>
<p>I am looking forward to 2010 with much excitement.</p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/x8BlqofbXCM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2009/12/31/looking-forward-to-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2009/12/31/looking-forward-to-2010/</feedburner:origLink></item>
		<item>
		<title>Don’t “fix”, improve!</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/ocgiqqnHESk/</link>
		<comments>http://www.liveandcode.com/2009/12/24/dont-fix-improve/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 19:50:41 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Personal Development]]></category>
		<category><![CDATA[new year]]></category>
		<category><![CDATA[self esteem]]></category>
		<category><![CDATA[self improvement]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=308</guid>
		<description><![CDATA[Perhaps it&#8217;s a sign that I have incredibly ambitious friends and acquaintances that they are already writing about making the coming year even more awesome than the last. Jon Crowley&#8217;s advice to those who are about to make New Year&#8217;s resolutions is not to try and &#8220;fix&#8221; themselves:
You can’t fix yourself.  You have to rebuild.
Take [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps it&#8217;s a sign that I have incredibly ambitious friends and acquaintances that they are already writing about making the coming year even more awesome than the last. <a title="Jon Crowley on Twitter" href="http://twitter.com/joncrowley">Jon Crowley</a>&#8217;s advice to those who are about to make New Year&#8217;s resolutions is <a title="brokentumblr. / Rebuild." href="http://joncrowley.tumblr.com/post/298697267/rebuild">not to try and &#8220;fix&#8221; themselves</a>:</p>
<blockquote><p>You can’t fix yourself.  You have to rebuild.</p>
<p>Take stock of who you are, where you are, and what has changed about your life and yourself.  And then do the things that will make you happier, make you smarter and better and stronger, and do them because you want to.  No one who is trying to fix a loss, or a heartache, is going to move on &#8211; if you do this, you are defining yourself by your tragedy.</p></blockquote>
<p>This is such an important point that I felt I needed to echo it and add a bit of my own experience to it.</p>
<p><span id="more-308"></span></p>
<p>I&#8217;ve made the mistake of trying to &#8220;fix&#8221; myself. I&#8217;ve continued making that mistake for very many years. Jon explains that we can&#8217;t fix ourselves because we are simply so complex that it&#8217;s like trying to patch the foundation of a building. I&#8217;ve discovered that there&#8217;s an even more sinister factor at work when we try to fix ourselves.</p>
<p><strong>To dedicate effort to fixing ourselves, we must first think that we are broken.</strong></p>
<p>It&#8217;s sinister because in our well-intentioned attempts to improve the things we do not like about ourselves, we are subconsciously reinforcing the belief that our current state is unacceptable, <em>that we are not good enough right now</em>. Nothing could be worse for self-esteem.</p>
<p>If you are truly &#8220;broken&#8221; you will heal with time, just as your body does. If you feel that the requisite time has passed but you are still deeply injured, I would suggest seeking professional help to put yourself firmly on the path to recovery (again, just as with our bodies). But if you assume you are broken, I challenge you to question that assumption.</p>
<p>My attempts at self-improvement had always started from the position that I am currently not acceptable and that I must fix myself to become good enough. But then I noticed situations in which I thought a lot worse of myself than others thought of me and it caused me to question the way I think about myself. <em>I realized that contrary to what I believed then, there is nothing fundamentally wrong with me. I am acceptable as I am now.</em></p>
<p>The lesson I have learned about trying to &#8220;fix&#8221; ourselves, then, is this:</p>
<p><strong>Start from the position of accepting yourself for what you currently are, then figure out how to do <em>even better</em>. Do not &#8220;fix&#8221;, improve!</strong></p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/ocgiqqnHESk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2009/12/24/dont-fix-improve/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2009/12/24/dont-fix-improve/</feedburner:origLink></item>
		<item>
		<title>Life advice in code</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/4UWAeZvpQ8c/</link>
		<comments>http://www.liveandcode.com/2009/12/21/life-advice-in-code/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 15:53:58 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Personal Development]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[life advice]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=298</guid>
		<description><![CDATA[Live &#38; Code has been largely about programming and life lessons. So, you can imagine that I was incredibly delighted to see these two combined in a small exchange on Facebook started by Reginald &#8220;raganwald&#8221; Braithwaite.
It&#8217;s a valuable life lesson made incredibly concise in my favourite programming language, Ruby. I leave the interpretation to the [...]]]></description>
			<content:encoded><![CDATA[<p>Live &amp; Code has been largely about programming and life lessons. So, you can imagine that I was incredibly delighted to see these two combined in a small exchange on Facebook started by Reginald &#8220;raganwald&#8221; Braithwaite.</p>
<div id="attachment_299" class="wp-caption aligncenter" style="width: 490px"><img class="size-full wp-image-299  " title="Life Advice in Code (raganwald)" src="http://www.liveandcode.com/wp-content/uploads/2009/12/Life-Advice-in-Code-raganwald.png" alt="Life Advice in Code (raganwald)" width="480" height="146" /><p class="wp-caption-text">Self-esteem expressed in Ruby</p></div>
<p style="text-align: left;">It&#8217;s a valuable life lesson made incredibly concise in my favourite programming language, Ruby. I leave the interpretation to the reader. It relates to some themes that I&#8217;ve already written about before and will probably write more about in the future.</p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/4UWAeZvpQ8c" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2009/12/21/life-advice-in-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2009/12/21/life-advice-in-code/</feedburner:origLink></item>
		<item>
		<title>LDAP-based RBAC with ActiveLdap and declarative_authorization</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/SiOAfWIPq00/</link>
		<comments>http://www.liveandcode.com/2009/12/14/ldap-based-rbac-with-activeldap-and-declarative_authorization/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:40:22 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[identity management]]></category>
		<category><![CDATA[ldap]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=271</guid>
		<description><![CDATA[If you followed my previous tutorial on implementing pass-through authentication to LDAP with Authlogic, you might be wondering how it can be extended to give different permissions to members of different LDAP groups. ActiveLdap and declarative_authorization make this incredibly simple.

As with the first tutorial, I&#8217;ve pushed a branch based on authlogic_example that you can use [...]]]></description>
			<content:encoded><![CDATA[<p>If you followed my <a title="LDAP Pass-through Authentication with Authlogic and ActiveLdap - Live &amp; Code" href="http://www.liveandcode.com/2009/08/30/ldap-pass-through-authentication-with-authlogic-and-activeldap/">previous tutorial</a> on implementing pass-through authentication to LDAP with Authlogic, you might be wondering how it can be extended to give different permissions to members of different LDAP groups. ActiveLdap and declarative_authorization make this incredibly simple.<br />
<span id="more-271"></span></p>
<p>As with the first tutorial, I&#8217;ve pushed a <a title="enricob's authlogic_example at ldap-rbac - GitHub" href="http://github.com/enricob/authlogic_example/tree/ldap-rbac">branch</a> based on <code>authlogic_example</code> that you can use as a concrete example.</p>
<p>First, let&#8217;s bring in the <a title="stffn's declarative_authorization at master - GitHub" href="http://github.com/stffn/declarative_authorization">declarative_authorization</a> gem:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># My example code was written before GitHub decided that they don't want to</span>
<span style="color:#008000; font-style:italic;"># build gems anymore but this line should do the trick.</span>
config.<span style="color:#9900CC;">gem</span> <span style="color:#996600;">&quot;declarative_authorization&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:source</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">'http://gemcutter.org'</span></pre></div></div>

<p>Now, we need to make an ActiveLdap model class like <code>LdapUser</code> but for groups. We&#8217;ll call this <code>LdapGroup</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> LdapGroup <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#6666ff; font-weight:bold;">ActiveLdap::Base</span>
  ldap_mapping <span style="color:#ff3333; font-weight:bold;">:dn_attribute</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;cn&quot;</span>,
    <span style="color:#ff3333; font-weight:bold;">:scope</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#ff3333; font-weight:bold;">:sub</span>,
    <span style="color:#ff3333; font-weight:bold;">:prefix</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;ou=groups,o=users&quot;</span>
&nbsp;
  has_many <span style="color:#ff3333; font-weight:bold;">:members</span>, <span style="color:#ff3333; font-weight:bold;">:class_name</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;LdapUser&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:wrap</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;member&quot;</span>,
    <span style="color:#ff3333; font-weight:bold;">:primary_key</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;dn&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:foreign_key</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;dn&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The <code>ldap_mapping</code> part is very similar to the previous one for <code>LdapUser</code>, but the <code>has_many</code> is where the real ActiveLdap magic starts!</p>
<p>We are letting ActiveLdap know that an <code>LdapGroup</code> has <code>LdapUser</code> members, which are defined in the multi-valued attribute <code>member</code>, where each of the values is the DN of an <code>LdapUser</code>. If you&#8217;re looking for a bit more detail, refer to the <a href="http://ruby-activeldap.rubyforge.org/doc/">ActiveLdap documentation</a>. Keep in mind that the code above is for the specific schema used by my example application and you may have to change it to match yours.</p>
<p>With that, we should be able to list all of our LDAP groups and find the members of any particular one in the console:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#006600; font-weight:bold;">&amp;</span>gt; LdapGroup.<span style="color:#9900CC;">all</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>g<span style="color:#006600; font-weight:bold;">|</span> g.<span style="color:#9900CC;">cn</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
=<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;super_admin&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#006600; font-weight:bold;">&amp;</span>gt; LdapGroup.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;super_admin&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">members</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>m<span style="color:#006600; font-weight:bold;">|</span> m.<span style="color:#9900CC;">dn</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
=<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;uid=ebianco,o=users,dc=example,dc=com&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Now we&#8217;ll create an association between <code>LdapUser</code> and <code>LdapGroup</code> so that given a user, we can figure out which groups he/she is a member of. We&#8217;re going to tell ActiveLdap that a user&#8217;s groups are those groups in which the user&#8217;s DN appears in the group&#8217;s <code>member</code> attribute:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">belongs_to <span style="color:#ff3333; font-weight:bold;">:groups</span>, <span style="color:#ff3333; font-weight:bold;">:class_name</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;LdapGroup&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:many</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;member&quot;</span>,
  <span style="color:#ff3333; font-weight:bold;">:foreign_key</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">&quot;dn&quot;</span></pre></div></div>

<p>Let&#8217;s check our handiwork in the console:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#006600; font-weight:bold;">&amp;</span>gt; LdapUser.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;ebianco&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">groups</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>g<span style="color:#006600; font-weight:bold;">|</span> g.<span style="color:#9900CC;">cn</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
=<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;super_admin&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Now why did we go through all of this effort? declarative_authorization allows us to provide an instance method for <code>User</code>, <code>#role_symbols</code>, that returns an array of symbols representing the list of roles that the user has. With our ActiveLdap setup, mapping a user&#8217;s roles to LDAP groups becomes a one-liner:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> role_symbols
  ldap_entry.<span style="color:#9900CC;">groups</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>g<span style="color:#006600; font-weight:bold;">|</span> g.<span style="color:#9900CC;">cn</span>.<span style="color:#9900CC;">to_sym</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>From here, we can define the authorization rules for our LDAP-based roles. declarative_authorization reads these from <code>config/authorization_rules.rb</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">authorization <span style="color:#9966CC; font-weight:bold;">do</span>
  role <span style="color:#ff3333; font-weight:bold;">:super_admin</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    has_permission_on <span style="color:#ff3333; font-weight:bold;">:users</span>, <span style="color:#ff3333; font-weight:bold;">:to</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#ff3333; font-weight:bold;">:manage</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  role <span style="color:#ff3333; font-weight:bold;">:guest</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    has_permission_on <span style="color:#ff3333; font-weight:bold;">:users</span>, <span style="color:#ff3333; font-weight:bold;">:to</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#ff3333; font-weight:bold;">:read</span>
    has_permission_on <span style="color:#ff3333; font-weight:bold;">:users</span>, <span style="color:#ff3333; font-weight:bold;">:to</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:update</span>, <span style="color:#ff3333; font-weight:bold;">:destroy</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      if_attribute <span style="color:#ff3333; font-weight:bold;">:id</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; is <span style="color:#006600; font-weight:bold;">&#123;</span>user.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
privileges <span style="color:#9966CC; font-weight:bold;">do</span>
  privilege <span style="color:#ff3333; font-weight:bold;">:manage</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    includes <span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:read</span>, <span style="color:#ff3333; font-weight:bold;">:update</span>, <span style="color:#ff3333; font-weight:bold;">:destroy</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now we can use declarative_authorization as usual. I won&#8217;t go through all the details but if you want a primer on using declarative_authorization, you can start <a title="README.rdoc at master from stffn's declarative_authorization" href="http://github.com/stffn/declarative_authorization/blob/master/README.rdoc">here</a> and browse the commits on my <code>authlogic_example</code> branch.</p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/SiOAfWIPq00" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2009/12/14/ldap-based-rbac-with-activeldap-and-declarative_authorization/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2009/12/14/ldap-based-rbac-with-activeldap-and-declarative_authorization/</feedburner:origLink></item>
		<item>
		<title>Rediscovering my music</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/nXeqJFs-eFU/</link>
		<comments>http://www.liveandcode.com/2009/11/24/rediscovering-my-music/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 02:13:46 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[me]]></category>
		<category><![CDATA[music]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=264</guid>
		<description><![CDATA[Years ago, I was torn between two passions. I had loved tinkering with computers and other electronic gadgets since I was as young as 10 (possibly younger!). But I also played the piano, taking lessons with my sisters and playing around with melodies and chords on the keys when I wasn&#8217;t practicing my lesson pieces.
That [...]]]></description>
			<content:encoded><![CDATA[<p>Years ago, I was torn between two passions. I had loved tinkering with computers and other electronic gadgets since I was as young as 10 (possibly younger!). But I also played the piano, taking lessons with my sisters and playing around with melodies and chords on the keys when I wasn&#8217;t practicing my lesson pieces.</p>
<p>That love of music carried into high school. I had stopped playing piano but in music class I picked up the clarinet quite quickly. I transferred to another school after grade 9 because the school I was in was planning to cut their music program entirely and I could not imagine being without it. At my new school, I was blown away when I heard the excellent performances of the senior jazz band and ensembles. I was fiercely determined to play with them but not many modern jazz arrangements called for a clarinet. So I learned to play saxophones.</p>
<p>At the same time, I continued tinkering with computers, teaching myself how to program because I wanted to program video games one day. An exhibit at the Ontario Science Centre featuring the &#8220;new&#8221; graphical web browsers, Netscape and Mosaic, inspired me to try my own hand at web publishing as soon as we were able to get connected to the Internet. In high school programming classes, I was well ahead of the curve, frequently finishing assignments meant to take hours in a matter of minutes.</p>
<p>And so, when I graduated from high school and decided I wanted to go to university, I had a difficult choice to make: which of these two things would I choose to focus on?<br />
<span id="more-264"></span></p>
<p>I ultimately decided that I was more passionate about computing and that it would also lead to a better career, so I decided to major in Computer Science.</p>
<p>Even then, I didn&#8217;t entirely stop playing music. I started taking clarinet lessons, intending to enhance my skills well beyond the intermediate proficiency I had achieved in high school. My teacher encouraged me to play for a youth symphony orchestra. My stand partner eventually became my first girlfriend and my stint with the orchestra culminated in a performance of <a href="http://www.youtube.com/watch?v=ptohdTEDjrI">von Weber&#8217;s Clarinet Concertino</a>.</p>
<p>I&#8217;m not sure exactly when it was, but I did eventually stop playing music to devote myself entirely to my Computer Science coursework and related projects. My clarinet has been sitting in storage for a long time, untouched, unplayed, <em>unloved</em>. The piano my sisters and I used to play is still in our family home, but has been in need of tuning for a very long time and has also been neglected.</p>
<p>I&#8217;ve begun my career as a web developer and I feel that I&#8217;ve made an excellent choice. But recently, I felt like I needed to bring music back into my life. Taking advantage of the Toronto Symphony Orchestra&#8217;s youth program, <a href="http://www.tsoundcheck.com/">tsoundcheck</a>, I bought a package of tickets for three concerts, two of which I&#8217;ve already attended. Now, also for the first time in years, I have thought about taking my clarinet out of storage, having it checked out, and playing it again.</p>
<p>I am rediscovering my art; <strong>I am rediscovering my music.</strong></p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/nXeqJFs-eFU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2009/11/24/rediscovering-my-music/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2009/11/24/rediscovering-my-music/</feedburner:origLink></item>
		<item>
		<title>Adventures in Ruby: When Constants Aren’t</title>
		<link>http://feedproxy.google.com/~r/LiveAndCode/~3/1S9K2g1VJbQ/</link>
		<comments>http://www.liveandcode.com/2009/11/16/adventures-in-ruby-when-constants-arent/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 18:14:48 +0000</pubDate>
		<dc:creator>Enrico</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[mystery]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.liveandcode.com/?p=249</guid>
		<description><![CDATA[I just squashed a bug that had me scratching my head for at least a good half-hour or so involving a class constant that kept on getting changed. Here&#8217;s the setup (anonymized so that I&#8217;m not exposing gooey proprietary secrets):

class WebTransaction
&#160;
  # Base URL for transaction web service
  SERVICE_URL = &#34;http://accountingservice.com/&#34;
&#160;
  def [...]]]></description>
			<content:encoded><![CDATA[<p>I just squashed a bug that had me scratching my head for at least a good half-hour or so involving a class constant that kept on getting changed. Here&#8217;s the setup (anonymized so that I&#8217;m not exposing gooey proprietary secrets):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> WebTransaction
&nbsp;
  <span style="color:#008000; font-style:italic;"># Base URL for transaction web service</span>
  SERVICE_URL = <span style="color:#996600;">&quot;http://accountingservice.com/&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> transaction_url
    url = SERVICE_URL
    url <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;VAL1=foo&quot;</span>
    url <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;&amp;VAL2=bar&quot;</span>
    url
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The class is meant to represent a transaction being posted against a rather odd web service that actually uses GET rather than POST for posting transactions (bad web service!). In my actual code, the URL parameters appended to the SERVICE_URL base would be determined on a per-object basis but I&#8217;ve simplified it here.</p>
<p>Here&#8217;s the punchline: <code>SERVICE_URL</code> was <em>changing!</em> Calls to <code>transaction_url</code> would keep on appending more variables to it. If you&#8217;re particularly clever with Ruby, you&#8217;ve already figured out exactly why. But if you&#8217;re scratching your head like I was, here are some hints:</p>
<ul>
<li>In Ruby, constants <em>aren&#8217;t</em>. In fact, they&#8217;re really no different from variables except for the fact that Ruby detects that variable names in all-caps are probably supposed to stay constant and warns if you try to assign to them.</li>
<li><code>&lt;&lt;</code>, for strings, will append to the end of the string.</li>
<li>Ruby strings are mutable. That is, operations on a string variable will usually be done in place, rather than returning a new string. (Method calls, on the other hand, are a different story!)</li>
<li>Assigning a String variable to another String variable will assign the reference. That is, the two variables will be pointing at the same object.</li>
</ul>
<p>Hit the jump to see the solution to this little mystery&#8230;<br />
<span id="more-249"></span></p>
<p><code>SERVICE_URL</code> is only directly assigned to when it is declared. But what happens when I assign <code>SERVICE_URL</code> to the local variable in <code>transaction_url</code>, <code>url</code>. <em>They&#8217;re pointing to the same object!</em></p>
<p>Then I go ahead and I start appending things to the end of the string. Ruby has no complaints because I&#8217;m not assigning to <code>SERVICE_URL</code> but <em>the object that it is pointing to is being changed!</em> The operation is causing the URL parameters to be appended in place.</p>
<p>And that, friends, is what happens when constants aren&#8217;t. Let&#8217;s fix this little error:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> WebTransaction
&nbsp;
  <span style="color:#008000; font-style:italic;"># Base URL for transaction web service</span>
  SERVICE_URL = <span style="color:#996600;">&quot;http://accountingservice.com/&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> transaction_url
    url = SERVICE_URL.<span style="color:#9900CC;">clone</span>
    url <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;VAL1=foo&quot;</span>
    url <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;&amp;VAL2=bar&quot;</span>
    url
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, instead of appending to the string object referenced by <code>SERVICE_URL</code> directly, I&#8217;m creating a copy of the object and then appending URL parameters to that.</p>
<img src="http://feeds.feedburner.com/~r/LiveAndCode/~4/1S9K2g1VJbQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.liveandcode.com/2009/11/16/adventures-in-ruby-when-constants-arent/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.liveandcode.com/2009/11/16/adventures-in-ruby-when-constants-arent/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.633 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-03-08 18:42:44 -->
