<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Code Dump &#187; tips</title>
	<atom:link href="http://www.codelord.net/tag/tips/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codelord.net</link>
	<description>A place a coder rants at...</description>
	<lastBuildDate>Sat, 04 Feb 2012 12:53:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Using Puppet to Automatically Configure New EC2 Instances</title>
		<link>http://www.codelord.net/2010/12/19/using-puppet-to-automatically-configure-new-ec2-instances/</link>
		<comments>http://www.codelord.net/2010/12/19/using-puppet-to-automatically-configure-new-ec2-instances/#comments</comments>
		<pubDate>Sun, 19 Dec 2010 20:30:48 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[techie]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=308</guid>
		<description><![CDATA[Note: I posted an update about doing the same with chef here. This is a quickie techie post that summarizes a few hours of learning that I wish someone else had put up on the web before me. I assume some knowledge about Puppet, and recommend the Pro Puppet book and heard good stuff about [...]]]></description>
			<content:encoded><![CDATA[<p><em>Note: I posted an update about doing the same with chef <a href="http://www.codelord.net/2011/03/07/using-chef-to-automatically-configure-new-ec2-instances/">here</a>.</em></p>
<p>This is a quickie techie post that summarizes a few hours of learning that I wish someone else had put up on the web before me. I assume some knowledge about Puppet, and recommend the <a href="http://www.amazon.com/gp/product/1430230576/ref=as_li_tf_tl?ie=UTF8&amp;tag=thcodu02-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399381&amp;creativeASIN=1430230576">Pro Puppet</a><img style="border: none !important; margin: 0px !important; display: none;" src="http://www.assoc-amazon.com/e/ir?t=thcodu02-20&amp;l=as2&amp;o=1&amp;a=1430230576&amp;camp=217145&amp;creative=399381" alt="" width="1" height="1" border="0" /> book and heard good stuff about <a href="http://www.amazon.com/gp/product/1849515387/ref=as_li_ss_tl?ie=UTF8&#038;tag=thcodu02-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1849515387">Puppet 2.7 Cookbook</a><img src="http://www.assoc-amazon.com/e/ir?t=thcodu02-20&#038;l=as2&#038;o=1&#038;a=1849515387" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important; display: none;" />.</p>
<p>So, I wanted to be able to configure via Puppet the way our new instances should be configured, and then be able to easily spawn new instances that will get configured by said puppet. The first part is <a href="https://help.ubuntu.com/10.10/serverguide/C/puppet.html">installing</a> puppetmaster. I decided to manually setup an EC2 instance that will act as the puppet master:</p>
<div id="gist-747614" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>aptitude install puppetmaster</div><div class='line' id='LC2'><span class="nb">echo</span> <span class="s2">&quot;127.0.0.1 puppet&quot;</span> &gt;&gt; /etc/hosts</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/747614/87c944d78d365d984535f4326cd87e988821989d/install_master.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/747614#file_install_master.sh" style="float:right;margin-right:10px;color:#666">install_master.sh</a>
            <a href="https://gist.github.com/747614">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<p>Under /etc/puppet/manifests/site.pp we place the &#8220;main&#8221; entry point for the configuration. This is the file that is responsible for including the rest of the files. I copied the structure from somewhere where the actual classes were put under /etc/puppet/manifests/classes and import it in site.pp. Do note that currently this setup only supports a single type of node, but supporting more should be doable using <a href="http://docs.puppetlabs.com/guides/external_nodes.html">external nodes</a> to classify the node types.</p>
<div id="gist-747614" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>import &quot;classes/*&quot;</div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'>node default {</div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include default_node</div><div class='line' id='LC5'>}</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/747614/f245c63d12b1a716975a518732451273c6f941f2/site.pp" style="float:right;">view raw</a>
            <a href="https://gist.github.com/747614#file_site.pp" style="float:right;margin-right:10px;color:#666">site.pp</a>
            <a href="https://gist.github.com/747614">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<div id="gist-747614" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>class default_node {</div><div class='line' id='LC2'>&nbsp;&nbsp;package { &#39;apache2&#39;:</div><div class='line' id='LC3'>&nbsp;&nbsp;&nbsp;&nbsp;ensure =&gt; installed</div><div class='line' id='LC4'>&nbsp;&nbsp;}</div><div class='line' id='LC5'>&nbsp;&nbsp;service { &#39;apache2&#39;:</div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;ensure =&gt; true,</div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;enable =&gt; true,</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;require =&gt; Package[&#39;apache2&#39;],</div><div class='line' id='LC9'>&nbsp;&nbsp;}</div><div class='line' id='LC10'>}</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/747614/29f0bd77a041cc3ef3817cb1a1f1c300830b77fe/classes/default_node.pp" style="float:right;">view raw</a>
            <a href="https://gist.github.com/747614#file_classes/default_node.pp" style="float:right;margin-right:10px;color:#666">classes/default_node.pp</a>
            <a href="https://gist.github.com/747614">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>Auto-signing new instances</h2>
<p>A common problem with puppet setups is that whenever a new puppet connects to the puppet master it hands it a certificate which you then have to automatically sign before the puppetmaster will agree to configure it. This is problematic in setups like mine where I want to be able to spawn new instances with a script and don&#8217;t hassle with jumping between the machines right after the certificate was sent and approving it. I found two ways to circumvent this:</p>
<h3>1. Simply auto-signing everything and relying on firewalls</h3>
<p>In case you can allow yourself to firewall the puppetmaster port (tcp/8140) to be only accessible to trusted instances, you do not actually need to sign the certificates, you can tell puppet to trust whatever it gets and leave the security in the hands of your trusty firewall. With EC2 this is extremely easy:</p>
<ul>
<li>Setup a security group, I&#8217;ll call mine &#8220;puppets&#8221;</li>
<li>Add a security exception to the puppetmaster that allows access to all instances in the &#8220;puppets&#8221; group</li>
<li>Create all puppet instances in the &#8220;puppets&#8221; security group</li>
<li>Configure puppet to automatically sign all requests: echo &#8220;*&#8221; &gt; /etc/puppet/autosign.conf</li>
</ul>
<p>I decided to go with this solution since it&#8217;s simpler and less likely to get broken. I didn&#8217;t see it documented anywhere else. The downside is that you&#8217;ve got to have your puppetmaster on EC2 too.</p>
<h3>2. Automatically identifying new instances and adding them</h3>
<p>This is a solution I saw mentioned a few times online. Using the <a href="http://aws.amazon.com/developertools/351?_encoding=UTF8&amp;jiveRedirect=1">EC2 API tools</a> write a script that gets the DNS names of all the trusted instances you&#8217;ve got and write them. Once you have this getting it to run with a cron job every minute will do the trick. This can be done with sophisticated scripts, but for my (<em>very initial</em>) testing, this seemed to work:</p>
<div id="gist-747614" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>* * * * * ec2-describe-instances | grep ^INSTANCE  | awk &#39;{print $4}&#39; &gt; /etc/puppet/autosign.conf</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/747614/09735ad7f806e8b2a06db2c7b160262653899313/cron" style="float:right;">view raw</a>
            <a href="https://gist.github.com/747614#file_cron" style="float:right;margin-right:10px;color:#666">cron</a>
            <a href="https://gist.github.com/747614">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>

<h2>Getting new instances to connect to the master</h2>
<p>The last piece of the puzzle. Since we use Ubuntu, we could simply use the <a href="http://alestic.com/2009/04/official-ubuntu-ec2">Canonical-supplied AMIs</a>. These support <a href="http://alestic.com/2009/06/ec2-user-data-scripts">user-data scripts</a> that are executed as root once the system boots. Below is a simple script that does this:</p>
<ol>
<li>Update the instance</li>
<li>Add the &#8220;puppet&#8221; entry to DNS &#8211; puppet expects the master to be accessible via &#8220;puppet&#8221; DNS resolution. This little snippet gets the current IP of the master via our DNS name and writes it to /etc/hosts</li>
<li>Install &amp; enable puppet and voila!</li>
</ol>
<div><div id="gist-747614" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c">#!/bin/bash</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="nb">set</span> -e -x</div><div class='line' id='LC4'><br/></div><div class='line' id='LC5'><span class="c"># Needed so that the aptitude/apt-get operations will not be interactive</span></div><div class='line' id='LC6'><span class="nb">export </span><span class="nv">DEBIAN_FRONTEND</span><span class="o">=</span>noninteractive</div><div class='line' id='LC7'><br/></div><div class='line' id='LC8'>apt-get update <span class="o">&amp;&amp;</span> apt-get -y upgrade </div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'><span class="c"># Find the current IP of the puppet master and make &quot;puppet&quot; point to it</span></div><div class='line' id='LC11'><span class="nv">puppet_master_ip</span><span class="o">=</span><span class="k">$(</span>host my_puppet_master.company.com | grep <span class="s2">&quot;has address&quot;</span> | head -1 | awk <span class="s1">&#39;{print $NF}&#39;</span><span class="k">)</span></div><div class='line' id='LC12'><span class="nb">echo</span> <span class="nv">$puppet_master_ip</span> puppet &gt;&gt; /etc/hosts</div><div class='line' id='LC13'><br/></div><div class='line' id='LC14'>aptitude -y install puppet </div><div class='line' id='LC15'><br/></div><div class='line' id='LC16'><span class="c"># Enable the puppet client</span></div><div class='line' id='LC17'>sed -i /etc/default/puppet -e <span class="s1">&#39;s/START=no/START=yes/&#39;</span></div><div class='line' id='LC18'><br/></div><div class='line' id='LC19'>service puppet restart</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/747614/831e2cac5e409f765ef9c742d867b2fde6ced5e7/start_puppet.sh" style="float:right;">view raw</a>
            <a href="https://gist.github.com/747614#file_start_puppet.sh" style="float:right;margin-right:10px;color:#666">start_puppet.sh</a>
            <a href="https://gist.github.com/747614">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</div>
<p>Once all of this is up and running, creating a new instance is as easy as:</p>
<p>ec2-run-instances -g puppets &#8211;user-data-file start_puppet.sh -t m1.small -k key-pair ami-a403f7cd</p>
<p>Happy puppeting!</p>
<p>You should subscribe to my <a href="http://feeds.feedburner.com/TheCodeDump">feed</a> and follow me on <a href="http://twitter.com/avivby">twitter</a>!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F12%2F19%2Fusing-puppet-to-automatically-configure-new-ec2-instances%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F12%2F19%2Fusing-puppet-to-automatically-configure-new-ec2-instances%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2010/12/19/using-puppet-to-automatically-configure-new-ec2-instances/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Short Intro to DRY</title>
		<link>http://www.codelord.net/2010/11/02/short-intro-to-dry/</link>
		<comments>http://www.codelord.net/2010/11/02/short-intro-to-dry/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 19:43:24 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[pragprowrimo2010]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[clean code]]></category>
		<category><![CDATA[DRY]]></category>
		<category><![CDATA[software craftsmanship]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=234</guid>
		<description><![CDATA[If you&#8217;re just starting to learn programming you might be feeling the need for a few solid guidelines for producing better code right now. Joining an industry with so many Best Practices, Rules of Thumb and The Right Things is not easy and certainly not too welcoming for newbies. One of the best programming mantras [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re just starting to learn programming you might be feeling the need for a few solid guidelines for producing better code right now. Joining an industry with so many Best Practices, Rules of Thumb and The Right Things is not easy and certainly not too welcoming for newbies.</p>
<p>One of the best programming mantras that everyone can understand and use for better code right away is DRY &#8211; Don&#8217;t Repeat Yourself. DRY is about removing duplication from the code base at pretty much every level, and this, I believe, is one of the pillars of good software engineering.</p>
<p>Academia rarely talks about DRY with enough stress. I&#8217;ve heard something like it only twice. Once, when I was told to use constants instead of magic numbers. This is maybe the simplest way to get started with DRY &#8211; replace magic numbers that you use several times in your code with a constant. All of a sudden the numbers got a real meaning but the more important thing is that changing the value becomes a no-brainer. Want to send more bytes with every packet? Just update the constant! That&#8217;s real value right there, instead of having to start searching files for the current number, and distinguishing between the times 512 is the packet size and when it&#8217;s just the maximal file size.</p>
<p>Another reference to DRY in Academia is &#8220;Reuse&#8221;. Reuse is the holy grail of software engineering. I know that after taking a few courses it seemed that Reuse is that peace of mind only OOP Gurus can get to by writing speckless code with good design. Although in academic courses you&#8217;re not likely to see real reuse and examples of code that reaches this goal in a good way, this is still a DRY manifestation that&#8217;s easy for a lot of people to grasp. What&#8217;s a better way to refrain from repeating myself than to not write new code at all and use that GenericAwesomeThing class I created before?</p>
<p>But, as with many things, those 2 well-rehearsed topics are only the tip of the DRY iceberg. Once you get it into your head that DRY is one of the easiest and most effective ways to get better and cleaner code, you&#8217;ll start seeing its violations left and right.</p>
<p>The easiest way to spot DRY violations is by looking at your typing. Pretty much any time you catch yourself using copy and paste, you know you&#8217;re doing it wrong. The mear act of copying some code around means, literally, you&#8217;re repeating the same thing somewhere else. Spotting those is usually a happy occasion, an opportunity to learn. This usually means you&#8217;re code is missing some basic abstraction to make that idea you&#8217;re trying to replicate a concrete concept of your system.</p>
<p>For example, whenever I copy a few lines from a method I know I probably need to extract a method. There are so many advantages to simply sticking to this as a golden rule that Uncle Bob is calling this &#8220;Extract till you Drop&#8221;. Practice DRY enough and &#8220;Extract Method&#8221; will become a regular coding step. It is no longer a &#8220;refactoring&#8221;. It is no longer a &#8220;task&#8221;. For me, it&#8217;s as simple as adding a variable, or writing a loop. It&#8217;s a tool, the simplest we&#8217;ve got.</p>
<p>But until you get familiar enough with extracting methods, you should be aware of these acts of copying stuff around and fight them with wrath. If extracting methods scares you, I&#8217;d start with even simpler stuff. Are you using the same string a couple of times, e.g. &#8220;Error: &#8221; is all over your code? Keep it DRY! Some simple computation appears a few times? Keep it DRY!</p>
<p>To start the ball rolling in the craftsmanship direction and adhering to what people that are wiser than you and I, keeping things DRY is a pretty simple, sure-fire way to do things better. Keep your watch for patterns that look all too similar. Imagine your keyboard has a DRY key that simply removes the duplication, be it by extracting a method, a constant or a class.</p>
<p>Try sticking a DRY post it to your monitor and do your best for a week. You will likely gain a whole new perspective of your code and learn to notice minute details you used to disregard. The magic is that once you start following DRY, you will also notice that the amount of places you need to go through to make changes is decreasing. There&#8217;s nothing better than finding that change you wanted to make is a one-line change, as there&#8217;s nothing more frustrating than finding out you now need to untangle 8 snippets in 5 files in order to get that simple change done.</p>
<p>DRY is a power tool you should master quickly and add to your tool box. I&#8217;ve written more about taking DRY further <a href="http://feeds.feedburner.com/TheCodeDump">here</a>.</p>
<p>You should subscribe to my <a href="http://feeds.feedburner.com/TheCodeDump">feed</a> and follow me on <a href="http://twitter.com/avivby">twitter</a>.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F11%2F02%2Fshort-intro-to-dry%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F11%2F02%2Fshort-intro-to-dry%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2010/11/02/short-intro-to-dry/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Avoid the perils of coder customers</title>
		<link>http://www.codelord.net/2010/02/20/avoid-the-perils-of-coder-customers/</link>
		<comments>http://www.codelord.net/2010/02/20/avoid-the-perils-of-coder-customers/#comments</comments>
		<pubDate>Sat, 20 Feb 2010 19:44:29 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=132</guid>
		<description><![CDATA[﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿Coders are the worst customers ever. The sooner you wrap your head around that, the better. Actually, any customer that&#8217;s technical is a bad customer, but nothing trumps coders. That fact is not intuitive, or at least wasn&#8217;t for me, but it can be really painful to find it out by yourself. So here, I [...]]]></description>
			<content:encoded><![CDATA[<p>﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿Coders are the worst customers ever. The sooner you wrap your head around that, the better. Actually, any customer that&#8217;s technical is a bad customer, but nothing trumps coders. That fact is not intuitive, or at least wasn&#8217;t for me, but it can be really painful to find it out by yourself. So here, I just saved you some agony.</p>
<p>Why are coders bad customers? First, let me say that even though coder-customers are a hard group to work with, they usually have really interesting problems to solve. After all, if it was simple they&#8217;d usually do it themselves. But, being coders, they think it&#8217;s acceptable to tell you how to do your job.</p>
<p>When you work with coders, the usual ticket/email/water-cooler chat will be of the form &#8220;you need to add an option for specifying X of type Y instead of the current options&#8221;. At this point they&#8217;ll usually start telling you how to implement that and how easy it is. If you&#8217;re like me, at this point your instinct will be to crank out the code and make your customer happy. Resist that urge like the plague!</p>
<p>Whenever I receive such a ticket, I dismiss everything in it. What I do next is come up to whoever suggested it, and ask &#8220;<strong>What is it that you&#8217;re trying to do?</strong>&#8221; Usually, this will result in exactly the same technical do-this-and-that explanation. Take a deep breath and ask the question again. This will usually be enough, but sometimes may require a couple more tries. That&#8217;s how you&#8217;re supposed to gather requirements &#8211; <strong>understand the problem at hand</strong>.</p>
<p>The main advantage of being a pain-in-the-ass and making sure you understand what it is you&#8217;re supposed to implement is because every coder should know exactly what his code is doing. A lot has been said about understanding the domain you&#8217;re working in, and simply implementing things handed to you is not the way to become knowledgeable in your domain.</p>
<p>Furthermore, once you hear what people are trying to do you might think of a better way of doing it, you being fully immersed in the existing code. Actually, more often than not you&#8217;ll see it&#8217;s actually already possible to do it! And best of all, you might simply decide that&#8217;s not a fair use of your code, and reject the ticket. How could you have made such a decision without knowing the actual problem you were asked to solve? No way.</p>
<p>Saying &#8220;no&#8221; to features is one of the most important design skills to master, and a tricky one. After all, turning to your keyboard, hacking the code and saying &#8220;presto!&#8221; is more fun at first. But that way of working leads to a code-base that you don&#8217;t really know. I&#8217;ve seen systems that were driven this way by technical users. 3 years later, there were rogue database fields that no one knew why there were being updated, and weird log files in awkward formats. Whenever someone tried removing one of those he found out it broke some dusty cron-job that seemed to use it instead of doing something sane (and do I really need to mention the code was a tangled, convoluted mess?).</p>
<p>Ask why, mindfully consider and then decide. There&#8217;s no really other way, unless you&#8217;d like to meet Code Cthulhu.</p>
<p>You should follow me on <a href="http://bit.ly/aU2CaB">twitter</a>.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F02%2F20%2Favoid-the-perils-of-coder-customers%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F02%2F20%2Favoid-the-perils-of-coder-customers%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2010/02/20/avoid-the-perils-of-coder-customers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Stop Coding in the Middle Ages</title>
		<link>http://www.codelord.net/2010/02/16/stop-coding-in-the-middle-ages/</link>
		<comments>http://www.codelord.net/2010/02/16/stop-coding-in-the-middle-ages/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 06:41:35 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=126</guid>
		<description><![CDATA[Aren&#8217;t you sick of wasting your time, your team&#8217;s time and precious build cycles for finding the stupidest mistakes ever? I know I&#8217;m far more interested in solving the real problems at hand than chasing stupid syntax errors. And even if you don&#8217;t mind, you really shouldn&#8217;t let your teammates substitute for a decent tool. [...]]]></description>
			<content:encoded><![CDATA[<p>Aren&#8217;t you sick of wasting your time, your team&#8217;s time and precious build cycles for finding the stupidest mistakes ever? I know I&#8217;m far more interested in solving the real problems at hand than chasing stupid syntax errors. And even if you don&#8217;t mind, you really shouldn&#8217;t let your teammates substitute for a decent tool.</p>
<p>Up until 15 years ago, I think it was very common for people to hack away at code for a good length of time, and once they got enough done, they&#8217;d try and compile the damn thing and start correcting the syntax errors, import things they forgot to, etc. This probably was because 15 years ago is the middle ages in computer-land, and compiling constantly was something people couldn&#8217;t even dream about on the little PCs we used to code on.</p>
<p>Nowadays, you can&#8217;t find more than a handful of static-language coders that won&#8217;t use a full featured IDE. C, Java, C# &#8211; other than a few freaky kernel hackers, I doubt anyone does real development outside an IDE in those languages. Today&#8217;s IDEs will tell you that you made a mistake about 2 seconds before you did. I never stop being amazed at how smart Eclipse is &#8211; and the first time I had to whip up some Java code in Vim, I felt handicapped.</p>
<p>What I find puzzling, is that people that are using the best available languages today, have suddenly decided that using the proper tool isn&#8217;t that important. Dynamic languages like Python and Ruby are not as easy to write awesome IDEs for, and therefore there aren&#8217;t many around that are mature enough, which is why it&#8217;s very common to see people use Emacs/Vim for coding them. Now don&#8217;t get me wrong, I&#8217;ve tried a few Python IDEs, but I&#8217;m still sticking with my Emacs. But when you use dynamic languages, you have to keep in mind you are even more prone of errors that will slip by. Even if you TDD, and your test coverage is extremely high, a typo might still get past your tests. Do you really want a production failure because you forgot to import an exception? (And do you really want to <a href="http://bit.ly/cKRZAK">upset Agnes</a>?)</p>
<p>About 2 weeks into my decision to stick with Emacs I started searching for simple tools that will protect me from my stupidity. It takes 10 minutes to find and install flymake with pyflakes (Python tool) support. Presto! No more typos in variable names, no more useless imports lying around. What surprised me is that a lot of my teammates, which I have respect for and are good programmers, did not use any of these. Time and time again our continuous integration system will report an error on a file and once I opened the file Emacs would show me the bad line marked with red, with no way of not noticing it.</p>
<p>I don&#8217;t like wasting my time, and I&#8217;m sure you don&#8217;t either. Stop being lazy (in the bad way). Stop making me angry. Get out of the middle ages. Yesterday we got everyone on my team to add pyflakes to their vim. Took 3 minutes to install. The problem is that it took more time to get them to install. &#8220;Nah, Vim already highlights syntax, there&#8217;s no need for more&#8221;. Oh really? After 10 minutes of searching I found a file that pyflakes showed a real problem in, and another, and another. &#8220;Hmmm, where do I download that plugin?&#8221; Win!</p>
<p>Do yourself, your team and your build slaves a favor, and start using some modern tools. I promise it will be worth it, money-back-guarantee. And remember, if your team is still churning butter, <a href="http://www.codelord.net/2009/04/04/sometimes-all-it-takes-is-a-little-push/">sometimes all it takes is a little push</a> (and sometimes you can plant bugs in their files).</p>
<p>You should follow me on <a href="http://bit.ly/aU2CaB">twitter</a>.
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F02%2F16%2Fstop-coding-in-the-middle-ages%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F02%2F16%2Fstop-coding-in-the-middle-ages%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2010/02/16/stop-coding-in-the-middle-ages/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Less Code is More</title>
		<link>http://www.codelord.net/2010/02/13/less-is-more/</link>
		<comments>http://www.codelord.net/2010/02/13/less-is-more/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 21:42:02 +0000</pubDate>
		<dc:creator>Aviv Ben-Yosef</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://www.codelord.net/?p=118</guid>
		<description><![CDATA[As coders, we should always strive to get as much feedback as soon as possible. Agile tells us we should get frequent feedback from our customers in order to make sure we&#8217;re always on track. Unit testing and the green-bar loving are all about knowing exactly when your code breaks and when you&#8217;re safe. A [...]]]></description>
			<content:encoded><![CDATA[<p>As coders, we should always strive to get as much feedback as soon as possible. Agile tells us we should get frequent feedback from our customers in order to make sure we&#8217;re always on track. Unit testing and the green-bar loving are all about knowing exactly when your code breaks and when you&#8217;re safe.</p>
<p>A kind of activity for which feedback is harder to get is our design. A big part of TDD is refactoring frequently. Refactoring often allows us to smooth out the design continuously as we work. The problem is, how can you tell you&#8217;ve done something good? On the one hand, creating abstractions is something good programmers do. On the other hand, taking that too far will usually cause more problems.</p>
<p>When making bigger changes, the best feedback will be from getting another pair of eyeballs go over the change. Pairing is the best way for getting a second opinion. Code reviews can be effective too. Problem is, a lot of people don&#8217;t get to pair or review most of their code (and yeah, I know that <a href="http://bit.ly/aSClmK">makes Corey Haines a sad panda</a>).</p>
<p>When I work by myself about the bigger things, there&#8217;s a handful of things I try to keep in mind, like the <a href="http://bit.ly/bs003B">SOLID principles</a>. But, the measure I like the most of how much shorter am I making the code. I&#8217;m not talking about obfuscating code. Readability is a must. I&#8217;m talking about abstractions that are really useful right now &#8211; they already make the code base smaller. Refactorings that make the code <a href="http://bit.ly/dizkHM">DRY</a> and thus shorter.</p>
<p><a href="http://codelord.net/wp-content/uploads/2010/02/67396-delete-key.jpg"><img class="aligncenter size-thumbnail wp-image-123" src="http://codelord.net/wp-content/uploads/2010/02/67396-delete-key-150x150.jpg" alt="delete key" width="150" height="150" /></a></p>
<p>Whenever I commit and git tells me I deleted more code than I inserted I get this fuzzy warm feeling. One of the <a href="http://bit.ly/cPw2Nr">agile manifesto principles</a> says &#8220;Simplicity &#8211; the art of maximizing the amount of work not done &#8211; is essential&#8221;. Problem is I&#8217;m not a perfect coder, and because of that I often perform more work than necessary. But I try to simplify my code when I notice this.</p>
<p>Paul Graham has an <a href="http://bit.ly/ae8RfK">essay</a> where he once showed a way for him to know he&#8217;s making good progress with Arc, the language he created. He kept track of the number of lines it took him to implement an application (Hacker News) and whenever he made some changes he checked to see if they made the application simpler.</p>
<p>Of course, as any rule, this one has exceptions. Eventually, you will need to add code! But, it always helps me see that what I thought was really good just adds clutter. Try and take a look at the output of <font style='color:#000000;background:#ffffff;'>git log <span style='color:#808030; '>-</span><span style='color:#808030; '>-</span>shortstat</font> &#8211; do you tend to add more lines whenever you clean up?</p>
<p>You should follow me on <a href="http://bit.ly/aU2CaB">twitter</a>!
<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F02%2F13%2Fless-is-more%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.codelord.net%2F2010%2F02%2F13%2Fless-is-more%2F&amp;source=avivby&amp;style=normal&amp;service=bit.ly&amp;service_api=R_6107bfac7c92ddff62b393d1e8b7abbe&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codelord.net/2010/02/13/less-is-more/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

