<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
 
 <title>Software By Josh</title>
 
 <link href="http://jcarver989.github.com/" />
 <updated>2012-03-12T00:19:38-07:00</updated>
 <id>http://jcarver989.github.com/</id>
 <author>
   <name>Joshua Carver</name>
   <email>jcarver989@gmail.com</email>
 </author>

 
 <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/softwarebyjosh" /><feedburner:info uri="softwarebyjosh" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
   <title>Fault Tolerant MongoDB on EC2</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/6Q4qL288mNo/elastic-ips-and-mongodb-replica-sets.html" />
   <updated>2012-03-11T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2012/03/11/elastic-ips-and-mongodb-replica-sets</id>
   <content type="html">&lt;h1&gt;Fault Tolerant MongoDB on EC2&lt;/h1&gt;
&lt;p&gt;While working on a project at &lt;a href="http://bizo.com"&gt;Bizo&lt;/a&gt; I needed to connect a Rails app to a MongoDB backend both of which run in Amazon&amp;#8217;s Cloud (EC2). At Bizo we have a policy to not use non Amazon services when possible (to limit risk) &amp;#8211; so we normally run most of our services straight off of EC2. I&amp;#8217;d like to share what I&amp;#8217;ve learned as best practices throughout the experience as I hope it might save some time and frustration for others.&lt;/p&gt;
&lt;h2&gt;Primer&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Replica+Sets"&gt;Replica sets&lt;/a&gt; are the preferred way to run a distributed, fault tolerant MongoDB service. But as with any distributed system, nodes will eventually fail. Now replica sets are pretty good at handling failures, but they can&amp;#8217;t save you if too many nodes fail.&lt;/p&gt;
&lt;p&gt;Specifically a replica set requires a minimum of two nodes to function at all times (1 primary and 1 secondary node). Thus a good rule of thumb is to run &lt;b&gt;at least 3 nodes&lt;/b&gt; in a replica set, that way if a node fails your database service doesn&amp;#8217;t go down with it. The Rails app I was working with doesn&amp;#8217;t experience enormous amounts of traffic so 3 m1.large (64bit) nodes were sufficient for my needs. What follows is a rundown of our setup and how it handles common needs of fault tolerant systems.&lt;/p&gt;
&lt;h2&gt;Best Practices&lt;/h2&gt;
&lt;h3&gt;&lt;b&gt;Minimize Failure with AutoScaling, Availability Zones, CloudWatch and &lt;span class="caps"&gt;EBS&lt;/span&gt; Volumes&lt;/b&gt;&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Use Autoscaling Groups, CloudWatch and &lt;span class="caps"&gt;EBS&lt;/span&gt; Volumes to replace failed nodes as soon as they go down. Since we run three nodes, our replica set is insulated from failure due to a single node crashing. But if two nodes crash the replica set goes with them. To solve this we use Cloudwatch alarms to trigger the Autoscaling Group whenever a node goes down &amp;#8211; that way a new replacement node is automatically brought online within a few minutes of a failure to reduce the risk of nodes sequentially failing. Additionally each node stores it&amp;#8217;s data on an &lt;span class="caps"&gt;EBS&lt;/span&gt; Volume (network attachable hard drive) &amp;#8211; that way when a node fails, it&amp;#8217;s replacement doesn&amp;#8217;t startup with missing data &amp;#8211; it simply mounts the previous node&amp;#8217;s &lt;span class="caps"&gt;EBS&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;To protect against multiple nodes failing simultaneously run each node in a separate availability zone. The above isn&amp;#8217;t sufficient to protect against things like hardware failures as all 3 instances could wind up on the same hardware. Running each node in a separate availability zone guarantees that our mongo instances run with a reasonable amount of separation (eg. they don&amp;#8217;t all end up on the same hardware box). Ideally you&amp;#8217;d run each node in its own region (separate data center), but this causes headaches trying to configure firewalls as Amazon does not allow security groups to be used across multiple regions (see security below). So unless you want to setup a &lt;span class="caps"&gt;VPN&lt;/span&gt; for cross region communication &amp;#8211; you&amp;#8217;re probably better off just running in separate availability zones.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Assuming you&amp;#8217;ve created the group and are running three nodes, each in a separate availability zone you can configure the auto scaling group using Amazon&amp;#8217;s &lt;a href="http://aws.amazon.com/developertools/2535"&gt;command line tools&lt;/a&gt; like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;as-update-auto-scaling-group my-mongo-service &lt;span class="se"&gt;\&lt;/span&gt;
--region us-east-1 &lt;span class="se"&gt;\&lt;/span&gt;
--availability-zones us-east-1a us-east-1b us-east-1c &lt;span class="se"&gt;\&lt;/span&gt;
--max-size 3 &lt;span class="se"&gt;\&lt;/span&gt;
--min-size 3 &lt;span class="se"&gt;\&lt;/span&gt;
--desired-capacity 3
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now if any node fails then a new one will startup to take its place in the proper availability zone.&lt;/p&gt;
&lt;h3&gt;If Everything Fails, have backups&lt;/h3&gt;
&lt;p&gt;It&amp;#8217;s always good to have backups just in case something really bad happens. Fortunately since we use &lt;span class="caps"&gt;EBS&lt;/span&gt; Volumes this is really easy &amp;#8211; we create nightly snapshots of the primary node&amp;#8217;s &lt;span class="caps"&gt;EBS&lt;/span&gt; Volume on our cron server using Amazon&amp;#8217;s command line tools (ec2-create-snapshot). These snapshots are persisted to S3 and we can easily restore our replica set from these backups.&lt;/p&gt;
&lt;h3&gt;Use Elastic IPs&lt;/h3&gt;
&lt;p&gt;As nodes fail and are replaced you want both your Replica set and your database clients to be able to find and connect to the new nodes. The easiest way to do this in Amazon is to use Elastic IPs &amp;#8211; special* static ip addresses that can be assigned to individual instances. Since each instance runs in a separate availability zone we just need one Elastic IP per zone. When a new node starts up to replace a failed instance, it checks which zone it was started in and assigns itself the matching Elastic IP. Both the client and replica set configuration should point at the Elastic IP address &amp;#8211; that way failures and startups of new nodes will be seamless to your app. This is because cross-security group openings in the firewall need to use internal (not external) addresses and the &lt;span class="caps"&gt;DNS&lt;/span&gt; url in the console will resolve to an internal ip address from an EC2 instance.&lt;/p&gt;
&lt;h3&gt;Security&lt;/h3&gt;
&lt;p&gt;This is where the headaches can start. Ideally you want to restrict access to your MongoDB instances to just your client application using Amazon&amp;#8217;s security groups. The way we normally set this up is to give your mongo instances a security group, say mongo-db-prod and your client app a security group, say cool-app-prod. Then mongo-db-prod would grant access on port 27017 (default mongodb port) to security group: cool-app-prod. Unfortunately what&amp;#8217;s not documented very well is that if you use the &lt;b&gt;external Elastic IP&lt;/b&gt; addresses in your configuration it &lt;b&gt;will not work&lt;/b&gt; with security groups! Instead you have to use the Elastic &lt;span class="caps"&gt;IPS&lt;/span&gt; &lt;span class="caps"&gt;DNS&lt;/span&gt; url (found in Amazon&amp;#8217;s web console) for security groups to work properly.&lt;/p&gt;
&lt;h3&gt;A Final Caveat&lt;/h3&gt;
&lt;p&gt;One thing to be careful of is if you require more than 5 nodes in a replica set you&amp;#8217;ll run into a problem using Elastic IPs &amp;#8211; Amazon by default only allows 5 eips per region. You&amp;#8217;ll need to either ask Amazon to increase this limit on your account or seek out an alternative setup.&lt;/p&gt;
&lt;p&gt;Well, that&amp;#8217;s it but If you have another setup for running MongoDB on EC2 I&amp;#8217;d love to here it. Until next time.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=6Q4qL288mNo:YSzXog1NWJo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=6Q4qL288mNo:YSzXog1NWJo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=6Q4qL288mNo:YSzXog1NWJo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=6Q4qL288mNo:YSzXog1NWJo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=6Q4qL288mNo:YSzXog1NWJo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=6Q4qL288mNo:YSzXog1NWJo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=6Q4qL288mNo:YSzXog1NWJo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=6Q4qL288mNo:YSzXog1NWJo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/6Q4qL288mNo" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2012/03/11/elastic-ips-and-mongodb-replica-sets.html</feedburner:origLink></entry>
 
 <entry>
   <title>Design Pattern: Threaded Requests with Retries</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/NUvW5dS62VM/design-pattern-threads-with-retries.html" />
   <updated>2012-02-29T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2012/02/29/design-pattern-threads-with-retries</id>
   <content type="html">&lt;h1&gt;Design Pattern: Threaded Requests with Retries&lt;/h1&gt;
&lt;p&gt;Imagine you have an amazing idea for the next great photo sharing app with Facebook integration. Never mind that there are already 10,000 more photo apps than the world needs right now &amp;#8211; to hell with the haters. You will make millions, people will love you and the world will be your oyster (err..figuratively speaking).&lt;/p&gt;
&lt;p&gt;But before you can ascend to the peak of photo sharing world domination &amp;#8211; you need to build the app. Naturally you&amp;#8217;ll need to communicate with Facebook, so you&amp;#8217;ll probably wind up using their &lt;a href="http://developers.facebook.com/docs/reference/api"&gt;Graph &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; along with some wrapper library for your favorite programming language. Let&amp;#8217;s assume you write the app in Ruby on Rails and you have some really simple Ruby class that wraps the api, like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FacebookApi&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth_credentials&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;# authentication stuff&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upload_photo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# logic to upload a photo to a user&amp;#39;s stream&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Great, your app can upload photos to Facebook now. But you can&amp;#8217;t just go running around willy-nilly calling the upload_photo() method &amp;#8211; everybody knows that networks are unreliable and can&amp;#8217;t be trusted to work all the time. Some of those photo uploads are bound to fail and you need to handle that somehow.&lt;/p&gt;
&lt;h2&gt;If at First You Don&amp;#8217;t Succeed, Try, Try Again&lt;/h2&gt;
&lt;p&gt;Lucky for you Facebook is a pretty reliable service &amp;#8211; any failures in your api requests are likely going to be fleeting &amp;#8211; simply retrying a failed upload a few times will probably work 99% of the time. Of course you want to wait a bit before retrying, eg. maybe an api method stops responding for a minute or two, or you temporarily lose your network connection.&lt;/p&gt;
&lt;p&gt;Ideally we&amp;#8217;d do this work in a background thread so we don&amp;#8217;t block the ui and we&amp;#8217;d have some kind of exponentially increasing delay between retries (because by the 3rd retry the chances of a 4th retry succeeding are minuscule).&lt;/p&gt;
&lt;h2&gt;Generalizing&lt;/h2&gt;
&lt;p&gt;Gee this situation seems familiar doesn&amp;#8217;t it? This kind of scenario (at least for me) crops up all the time in web apps &amp;#8211; ex. make a call to some webservice, if it didn&amp;#8217;t work try again a few times and if that doesn&amp;#8217;t work log something useful and give up. It&amp;#8217;d be great to have some reusable design pattern for this type of situation. Fortunately this turns out to be pretty trivial to do in Ruby (or most languages actually).&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll show you a simple example of what this might look like in Rails and break down what&amp;#8217;s happening below the code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="c1"&gt;# lib/threaded_api_call.rb&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadedApiCall&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;execute_in_thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DEFAULT_OPTS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;
    &lt;span class="vi"&gt;@thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;result&lt;/span&gt;
    &lt;span class="vi"&gt;@result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_in_thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
      &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="n"&gt;wait_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_attempts&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;begin&lt;/span&gt;
          &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="vi"&gt;@result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;
        &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
          &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:logger&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;request failed for: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
          &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:logger&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;will retry in &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;wait_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; seconds&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attempts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_attempts&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
          &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="n"&gt;wait_time&lt;/span&gt;

          &lt;span class="c1"&gt;# exponential backoff between retries&lt;/span&gt;
          &lt;span class="n"&gt;wait_time&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:wait_interval&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;ensure&lt;/span&gt;
          &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:logger&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="no"&gt;DEFAULT_OPTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:name&lt;/span&gt;          &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;generic api request&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:max_attempts&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:logger&lt;/span&gt;        &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;:wait_interval&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;# seconds&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Basically we just create a class that takes in a hash of options and a block (similar to a function pointer or lambda in other languages &amp;#8211; if you&amp;#8217;re unfamiliar with Ruby the differences are immaterial for this example). When the class is initialized the block is executed inside of a new thread (to avoid blocking our main thread), if anything goes wrong we simply try again with an exponentially increasing cooldown interval (options[:wait_interval] is the base) up to a maximum number of retries (options[:max_attempts]). Finally if we exceed the maximum retries, we give up and log everything to options[:logger] which defaults to the Rails.logger (make sure to remember to always call flush!).&lt;/p&gt;
&lt;p&gt;If for some reason you need to stop the main thread and wait for results to come back, you still can by calling join (just like a normal Ruby thread) and then call result().&lt;/p&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Since we keep our concurrency and api integration code separate this ends up being trivial to test. For our ThreadedApiCall class all we have to do is use a mock/spy or a simple counter. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;ThreadedApiCall&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;executes the block passed to it one time on success&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;test_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
      &lt;span class="n"&gt;test_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:call&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exactly_once&lt;/span&gt;

      &lt;span class="no"&gt;ThreadedApiCall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:test_api&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;test_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;retries the block passed to it if failed the first time&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;num_calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; 

      &lt;span class="n"&gt;api_call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ThreadedApiCall&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c1"&gt;# pretend we fail on first try&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num_calls&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
          &lt;span class="n"&gt;num_calls&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; 
          &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;FAIL!&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="n"&gt;num_calls&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="n"&gt;num_calls&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;api_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;
      &lt;span class="n"&gt;api_call&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# etc for other test cases &lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Using and Abusing&lt;/h2&gt;
&lt;p&gt;The great thing about this approach is when you add Google+ and Flickr integration into your &lt;strong&gt;amazing&lt;/strong&gt; web app you can easily reuse this class to wrap your &lt;span class="caps"&gt;API&lt;/span&gt; calls &amp;#8211; so you get threaded retries, logging and exponential backoff all for free!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=NUvW5dS62VM:phDB-rE67eY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=NUvW5dS62VM:phDB-rE67eY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=NUvW5dS62VM:phDB-rE67eY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=NUvW5dS62VM:phDB-rE67eY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=NUvW5dS62VM:phDB-rE67eY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=NUvW5dS62VM:phDB-rE67eY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=NUvW5dS62VM:phDB-rE67eY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=NUvW5dS62VM:phDB-rE67eY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/NUvW5dS62VM" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2012/02/29/design-pattern-threads-with-retries.html</feedburner:origLink></entry>
 
 <entry>
   <title>Building a Product in Just 8 Hours</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/ca1Yt7Dj9Vk/building-a-product-in-just-8-hours.html" />
   <updated>2012-02-17T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2012/02/17/building-a-product-in-just-8-hours</id>
   <content type="html">&lt;h1&gt;Building a Product in Just 8 Hours&lt;/h1&gt;
&lt;p&gt;Cross posted on the &lt;a href="http://dev.bizo.com"&gt;Bizo Dev Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Recently at my employer, &lt;a href="http://bizo.com"&gt;Bizo&lt;/a&gt;, we decided to try a new kind of hack day. Previously during hackdays our engineers worked individually on their own project(s). But on our last hack day we decided to try something new &amp;#8211; &lt;b&gt;The 8 Hour Product Challenge&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;We would build and launch a completely new product in the course of a normal workday (9-5pm). &amp;#8220;Launching&amp;#8221; meant this product had to be running publicly on the internet by 5pm &amp;#8211; no excuses, no &amp;#8220;Wait! I need 5 more minutes&amp;#8221; &amp;#8211; whatever was there had to be deployed. In short the experience was fantastic and I can&amp;#8217;t wait to do it again. Here&amp;#8217;s a breakdown of the experience:&lt;/p&gt;
&lt;h2&gt;Initial Meeting &lt;small style="color: #555; font-weight: normal;"&gt;9:30am&lt;/small&gt;&lt;/h2&gt;
&lt;p&gt;Organizing developers for a meeting of any kind is like trying to heard cats. But if it&amp;#8217;s a meeting before 11:00am you&amp;#8217;re not herding regular cats, you&amp;#8217;re herding sleepy, fat cats with one leg and half an ear. Somehow after a lot of cattle prodding by our &lt;a href="https://github.com/floodfx"&gt;VP of engineering&lt;/a&gt; our team eventually managed to shuffle its way into the conference room like the decaffeinated zombies we were and get to work.&lt;/p&gt;
&lt;p&gt;We decided to build a stealth product. The system would use &lt;a href="http://www.bizo.com/bizographics/index"&gt;Bizo&amp;#8217;s rich business data&lt;/a&gt; to personalize special content for visitors based on things like their industry, company size and seniority. The goal for the end of the day was to have a small webapp up and running on Amazon&amp;#8217;s servers.&lt;/p&gt;
&lt;p&gt;After a bit more discussion, we decided to split tasks up into five groups of two engineers:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;Data Discovery Team&lt;/b&gt;   &amp;#8211; Find relevant items for users by using our B2B business data &amp;amp; network.&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Scraping Team&lt;/b&gt;     &amp;#8211; given a url representing an item scrape the page contents and store them for later use&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Data Classification Team&lt;/b&gt;  &amp;#8211;  extract relevant data from the &lt;span class="caps"&gt;HTML&lt;/span&gt; source of the previously scraped urls.&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Backend Team&lt;/b&gt;   &amp;#8211; backend architecture for the webapp that fetches serves the content from that was generated in the previous steps&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Frontend Team&lt;/b&gt;  &amp;#8211; frontend design + javascript that makes the app functional&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Engineers were assigned more or less randomly, with the exception of myself &amp;#8211; I was assigned to the frontend team directly.&lt;/p&gt;
&lt;p&gt;During the course of our initial planning meeting, we (myself included) often found ourselves becoming sidetracked with feature bloat, premature scalability concerns and a myriad of other things not essential to our &lt;span class="caps"&gt;MVP&lt;/span&gt;. Fortunately one of my coworkers (&lt;a href="http://draconianoverlord.com"&gt;Stephen&lt;/a&gt;) was smart enough to enforce timeboxing the meeting to one hour &amp;#8211; eventually we got things back on topic and designed the critical components before time ran out.&lt;/p&gt;
&lt;h2&gt;Start Work &lt;small style="color: #555; font-weight: normal;"&gt;10:30am&lt;/small&gt;&lt;/h2&gt;
&lt;p&gt;Once the teams were assigned, we all jumped in and started to work on our relevant tasks. My partner, &lt;a href="https://github.com/balshor"&gt;Darren&lt;/a&gt; and I immediately started out by sketching ideas on paper for our design. I can&amp;#8217;t stress enough how important sketching is for being able to rapidly prototype a product &amp;#8211; a trick I picked up back when I interned over at &lt;a href="http://zurb.com"&gt;&lt;span class="caps"&gt;ZURB&lt;/span&gt;&lt;/a&gt;. Only after we had some solid sketches did we move into Photoshop mockups. Meanwhile the other teams were all furiously programming their parts of the application:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;Data Discovery Team&lt;/b&gt; Worked out a simple ranking algorithm for data and started writing the &lt;a href="https://cwiki.apache.org/confluence/display/Hive/Home%3bjsessionid=E3548DACBC8C6E9EC8EBE15F65B8CF57"&gt;Hive&lt;/a&gt; script to extract it.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;&lt;span class="caps"&gt;URL&lt;/span&gt; Scraping Team&lt;/b&gt; Started out in Scala hacking up a script to scrape &amp;amp; download url content.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;Data Extraction Team&lt;/b&gt; Decided to try out the &lt;a href="http://rubygems.org/gems/pismo"&gt;Pismo&lt;/a&gt; gem to extract summaries and titles from scraped html content.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;Backend Team&lt;/b&gt; Was working on getting a sweet &lt;a href="http://www.scalatra.org/"&gt;Scalatra&lt;/a&gt; webapp up and running&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lunch Time &amp;amp; Status Updates &lt;small style="color: #555; font-weight: normal;"&gt;12:30pm&lt;/small&gt;&lt;/h2&gt;
&lt;p&gt;By lunchtime everything seemed to be coming along nicely. On the frontend had completed our Photoshop mockup and had just began writing some basic css styles. All the other teams reported making good progress on their tasks, with no major snags in the foreseeable future (betcha you never heard that one before&amp;#8230;).&lt;/p&gt;
&lt;h2&gt;Afternoon &lt;small style="color: #555; font-weight: normal;"&gt;1:30pm&lt;/small&gt;&lt;/h2&gt;
&lt;p&gt;My frontend partner and I powered through our post lunch food coma and were able to move into begin wiring up the ui using CoffeeScript in conjunction with &lt;a href="http://github.com/jcarver989/dependence.js"&gt;Dependence.js&lt;/a&gt;. My teammate and I decided to give pair programming a shot. He has always been more of an Emacs kind of guy, while I prefer vi, but in the interests of learning I decided to try Emacs for the rest of the day &amp;#8211; I now know why he&amp;#8217;s always so worried about contracting carpel tunnel syndrome :).&lt;/p&gt;
&lt;p&gt;Using some sample data generated by the first three teams we were able to get a rough ui working pretty quickly. Our side of things turned out to be pretty straightforward and involved three &lt;span class="caps"&gt;AJAX&lt;/span&gt; requests. One was to retrieve a list of items grouped by segment from the Scalatra web server, one to get a list of the current targetable segments from the &lt;a href="http://developer.bizo.com/"&gt;Bizo &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; and another call to the &lt;span class="caps"&gt;API&lt;/span&gt; to retrieve a visitor&amp;#8217;s business segments (bizographics).&lt;/p&gt;
&lt;p&gt;The only snag we hit was running into a race condition &amp;#8211; originally we attempted executing all three requests simultaneously. In reality we had to wait to get the list of segments before getting the visitor&amp;#8217;s profile. Darren and I just looked at each other and shrugged, then we indented the third &lt;span class="caps"&gt;API&lt;/span&gt; request a few spaces in our CoffeeScript code &amp;#8211; race condition solved! Yes that&amp;#8217;s correct we fixed a race condition by indenting some code, don&amp;#8217;t judge &amp;#8211; it was a hackday.&lt;/p&gt;
&lt;p&gt;The other teams all seemed to be doing well, the scraping team discovered the Scala Collection&amp;#8217;s magical par(), which turns normal data structures into parallel ones, they almost peed their pants with joy. At this point the backend team had completed the Scalatra app and was working on setting up our eventual deployment to EC2 using our custom infrastructure, cowboy.&lt;/p&gt;
&lt;h2&gt;The Home Stretch &amp;amp; Deployment &lt;small style="color: #555; font-weight: normal;"&gt;4:30pm&lt;/small&gt;&lt;/h2&gt;
&lt;p&gt;Right around 4:30 we ran into a major problem. There had been a miscommunication regarding the necessary format of the &lt;span class="caps"&gt;JSON&lt;/span&gt; file needed by the frontend, and our data was coming through to the app in a format that just wouldn&amp;#8217;t work. We had to scramble and hash things out with the other teams quickly before we hit our 5pm deadline. Thanks to a major push by the Data Extraction Team we were finally able to get everything in place. The product worked! &amp;#8211; it wasn&amp;#8217;t the most polished app ever, but what we had accomplished in just one day was pretty amazing. The product was deployed on EC2 and presented internally within Bizo &amp;#8211; it was met with a lot of excitement and Bizo will probably be releasing it publicly in the weeks to come.&lt;/p&gt;
&lt;h2&gt;Closing Thoughts&lt;/h2&gt;
&lt;p&gt;Overall the experiment turned out to be a smash hit. Looking back on the experience there are a bunch of things we could have done better. In retrospect we got sidetracked a bit too much on non essential feature ideas when we really should have been spending time clarifying the format of the data as it passed through each team&amp;#8217;s project &amp;#8211; this was something that came back and bit us near the end of the day. But mishaps aside it&amp;#8217;s really amazing what you can accomplish with 9 other talented people in a single day.&lt;/p&gt;
&lt;p&gt;I can&amp;#8217;t recommend trying this with your team enough &amp;#8211; what do you think, is your engineering team up for The 8 Hour Product Challenge? If you&amp;#8217;re interested in the technologies we used throughout the day, see below.&lt;/p&gt;
&lt;h2&gt;Appendix, Technologies Used&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;News Discovery Team&lt;/b&gt;   &amp;#8211; Hive, Amazon EC2, Amazon S3&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;&lt;span class="caps"&gt;URL&lt;/span&gt; Scraping Team&lt;/b&gt;     &amp;#8211; Scala&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Data Extraction Team&lt;/b&gt;  &amp;#8211; jRuby, gems of note: pismo, right_aws (for Amazon S3)&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Backend Team&lt;/b&gt;   &amp;#8211; Scalatra, Amazon S3&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Frontend Team&lt;/b&gt;  &amp;#8211; Photoshop, HTML5, Sass, CoffeeScript, jQuery, dependence.js&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=ca1Yt7Dj9Vk:g10XqlMjxMw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=ca1Yt7Dj9Vk:g10XqlMjxMw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=ca1Yt7Dj9Vk:g10XqlMjxMw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=ca1Yt7Dj9Vk:g10XqlMjxMw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=ca1Yt7Dj9Vk:g10XqlMjxMw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=ca1Yt7Dj9Vk:g10XqlMjxMw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=ca1Yt7Dj9Vk:g10XqlMjxMw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=ca1Yt7Dj9Vk:g10XqlMjxMw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/ca1Yt7Dj9Vk" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2012/02/17/building-a-product-in-just-8-hours.html</feedburner:origLink></entry>
 
 <entry>
   <title>Stop Wasting Time Setting Up Frontend Projects</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/4PMB3eqEz_o/stop-wasting-time-setting-up-frontend-projects.html" />
   <updated>2012-01-29T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2012/01/29/stop-wasting-time-setting-up-frontend-projects</id>
   <content type="html">&lt;h1&gt;Stop Wasting Time Setting Up Frontend Projects&lt;/h1&gt;
&lt;p&gt;Setting up a new project and its dependencies in most languages is a pain, but particularly so on the frontend where you have lots of separate tools like CoffeeScript, Sass, HTML5 and various 3rd Party JS libs like jQuery all (supposedly) working together. A lot of programmers I&amp;#8217;ve met dismiss the time wasted while setting up a new project as a &amp;#8220;one time fee&amp;#8221;. But in reality most programmers set up new projects all the time &amp;#8211; work projects, projects for fun, side projects etc.  We shouldn&amp;#8217;t be repeatedly wasting time setting up a new project when we could be writing something relevant instead. This kind of problem is ripe for automation.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s why tonight I hacked together a little Ruby script &lt;a href="https://github.com/jcarver989/frontend-launchpad"&gt;Frontend-Launchpad&lt;/a&gt; to setup new frontend projects with all the bells and whistles I normally use. While most of the tools it sets up are my own &amp;#8211; I&amp;#8217;m a eat my own dog food kind of guy (figuratively, not litterally) &amp;#8211; you could easily modify the script to suit your own needs.&lt;/p&gt;
&lt;h2&gt;Features&lt;/h2&gt;
&lt;p&gt;Out of the box, you get the following:&lt;/p&gt;
&lt;h3&gt;CoffeeScript + Sass&lt;/h3&gt;
&lt;p&gt;Frontend-Launchpad generates a build script for you that compiles your .coffee and .sass files. CoffeeScript files are compiled and minified using &lt;a href="https://github.com/jcarver989/dependence.js"&gt;Dependence&lt;/a&gt; with no setup required beyond installing the gem.&lt;/p&gt;
&lt;h3&gt;Optional Modules&lt;/h3&gt;
&lt;p&gt;The launchpad script will optionally install the following modules into your new project:&lt;/p&gt;
&lt;p&gt;1. &lt;a href="http://jquery.com"&gt;jQuery&lt;/a&gt; the dom library we all know and love&lt;br /&gt;
2. &lt;a href="http://softwarebyjosh.com/raphy-charts"&gt;Raphy Charts&lt;/a&gt; beautiful HTML5/&lt;span class="caps"&gt;SVG&lt;/span&gt;/&lt;span class="caps"&gt;VML&lt;/span&gt; charts, if I do say so myself &lt;br /&gt;
3. &lt;a href="https://github.com/jcarver989/state_machine.js"&gt;StateMachine.js&lt;/a&gt; easy custom events finite state machines&lt;br /&gt;
4. &lt;a href="https://github.com/jcarver989/phantom-jasmine"&gt;JasmineTests&lt;/a&gt; superfast command line &lt;a href="http://pivotal.github.com/jasmine/"&gt;Jasmine&lt;/a&gt; tests with &lt;a href="http://phantomjs.org"&gt;PhantomJS&lt;/a&gt;&lt;br /&gt;
5. &lt;a href="http://softwarebyjosh.com/pretty-pieces.sass/"&gt;PrettyPieces&lt;/a&gt; like Twitter Bootstrap, but for Sass&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;p&gt;Installation should be really easy, just grab the script from the link below and run the code below. Note* you&amp;#8217;ll probably want to put this script on your path for easy reuse and tab completion.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;git clone https://jcarver989@github.com/jcarver989/frontend-launchpad.git

&lt;span class="nb"&gt;cd &lt;/span&gt;frontend-launchpad 
./launch.rb foo_project 

&lt;span class="c"&gt;# follow the prompts to install modules...&lt;/span&gt;

&lt;span class="nb"&gt;cd &lt;/span&gt;foo_project &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./build.sh

&lt;span class="c"&gt;# Your shiny new project is ready to go &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/jcarver989/frontend-launchpad" class="medium green bordered pill button"&gt;Get Frontend-Launchpad&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Extension&lt;/h2&gt;
&lt;p&gt;This script only me a short time to hack together so if this script doesn&amp;#8217;t suit your needs (ex you want to use Bootstrap), feel free to extend it &amp;#8211; send me pull requests and/or fork it for your own usage. Whatever you do, don&amp;#8217;t waste time manually setting up another frontend project manually again! Until next time, cheers.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=4PMB3eqEz_o:Kp1rOrawZA8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=4PMB3eqEz_o:Kp1rOrawZA8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=4PMB3eqEz_o:Kp1rOrawZA8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=4PMB3eqEz_o:Kp1rOrawZA8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=4PMB3eqEz_o:Kp1rOrawZA8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=4PMB3eqEz_o:Kp1rOrawZA8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=4PMB3eqEz_o:Kp1rOrawZA8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=4PMB3eqEz_o:Kp1rOrawZA8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/4PMB3eqEz_o" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2012/01/29/stop-wasting-time-setting-up-frontend-projects.html</feedburner:origLink></entry>
 
 <entry>
   <title>Pirating Ruby Methods For Fun And Profit</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/8tBn7V5BVCE/Pirating-Ruby-Methods-For-Fun-And-Profit.html" />
   <updated>2012-01-21T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2012/01/21/Pirating-Ruby-Methods-For-Fun-And-Profit</id>
   <content type="html">&lt;h1&gt;Pirating Ruby Methods For Fun And Profit&lt;/h1&gt;
&lt;p&gt;With all the &lt;span class="caps"&gt;SOPA&lt;/span&gt; coverage lately I wanted to post about software piracy (yarrrr!). But this post isn&amp;#8217;t about the kind of software piracy you&amp;#8217;re used to hearing about &amp;#8211; it&amp;#8217;s about pirating object methods using Ruby.&lt;/p&gt;
&lt;p&gt;Sometimes while programming you might want to do what I call &lt;b&gt;pirating a method&lt;/b&gt;  &amp;#8211; where you augment an object by borrowing a method from another module or class. Method pirating is fairly common to see in JavaScript code, especially to augment array-like objects like arguments which don&amp;#8217;t have some useful methods that Arrays have, ex: &lt;a href="http://www.w3schools.com/jsref/jsref_slice_array.asp" title=""&gt;Array.slice&lt;/a&gt;. Rubyists however aren&amp;#8217;t quite the scallywags that JavaScript programmers are and don&amp;#8217;t tend to do much pirating, but there&amp;#8217;s times in Ruby where method pirating can be useful.&lt;/p&gt;
&lt;h2&gt;Including only what you need, nothing you don&amp;#8217;t&lt;/h2&gt;
&lt;p&gt;Suppose that we have an extremely simple LinkedList implementation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@head&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;

    &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@head&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;each&lt;/span&gt;
    &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@head&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;
      &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;
    &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;
    &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:next&lt;/span&gt;
    &lt;span class="kp"&gt;attr_reader&lt;/span&gt;   &lt;span class="ss"&gt;:value&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# comparison operator&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;&amp;lt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now imagine we&amp;#8217;d like to add a map (collect) method onto our LinkedList. We could implement this ourselves, but the &lt;a href="http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-map"&gt;Enumerable&lt;/a&gt; module already has the exact method we want. There is no need to reinvent the wheel &amp;#8211; so we should find a way to make use of it.&lt;/p&gt;
&lt;h3&gt;Option #1: Mixin Enumerable&lt;/h3&gt;
&lt;p&gt;We could easily add Enumerable&amp;#8217;s map() method to our LinkedList implementation by simply including the Enumerable module into our class like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Enumerable&lt;/span&gt;
  &lt;span class="c1"&gt;# rest of implementation&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Since we already implemented an each() method, Enumerable&amp;#8217;s map() methods will automatically work with our LinkedList class &amp;#8211; nice! The downside to this approach is that a bunch of other methods we didn&amp;#8217;t need came along for the ride like min(), max(), reduce() (inject) &amp;#8211; in fact  every instance method defined in Enunmerable is now a part of LinkedList.&lt;/p&gt;
&lt;p&gt;Now in Enumerable&amp;#8217;s case this isn&amp;#8217;t a disaster &amp;#8211; we only had to define one method (each) to make Enumerable work with LinkedList. But more complex mixins might require several helper methods to be defined to work with classes that include them. If we only want one or two methods from a module that don&amp;#8217;t require extra helper methods &amp;#8211; that could be a lot of extra work defining methods for functionality we don&amp;#8217;t need.&lt;/p&gt;
&lt;h3&gt;Option #2: Pirating, Yarrr!&lt;/h3&gt;
&lt;p&gt;If you only want a few methods that a module provides, then a better option might be to pirate that method instead.&lt;/p&gt;
&lt;p&gt;In my &lt;a href="/2012/01/08/How-To-Write-Your-Own-DSL.html"&gt;last post on writing DSL&amp;#8217;s&lt;/a&gt; I showed how we could do this using instance_eval to change the execution context of a block. This seems like a reasonable approach to pirating methods as we could turn a regular module method into a block and then attempt to execute it in the context of the class stealing the method. Let&amp;#8217;s give it a shot:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Foo&lt;/span&gt; 
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hi&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="vi"&gt;@words&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Boo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;boo&amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt; 

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hi&lt;/span&gt;
    &lt;span class="nb"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Foo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:hi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;instance_eval&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;boo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Boo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;span class="n"&gt;boo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hi&lt;/span&gt;

&lt;span class="c1"&gt;# wrong argument type UnboundMethod (expected Proc) (TypeError)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Uh-oh, looks like we wound up with an &lt;a href="http://www.ruby-doc.org/core-1.9.3/UnboundMethod.html"&gt;UnboundMethod&lt;/a&gt;, which isn&amp;#8217;t associated with an object and thus uncallable. That&amp;#8217;s ok though since in this case we&amp;#8217;d like to bind our new unbound hi() method to the the Boo class so Boo.hi functions properly.&lt;/p&gt;
&lt;p&gt;There is one issue though, UnboundMethods can only be bound to the same object type that they were created from. Ex. since we created an unbound method from Foo, we can only bind that method to another instance of Foo. Boo does not use Foo as a mixin so we&amp;#8217;re currently unable to bind an UnboundMethod from Foo to an instance of Boo.&lt;/p&gt;
&lt;p&gt;Fortunately Ruby allows to cheat. We can create a temporary Boo object that extends Foo without altering any other Boo instances using &lt;a href="http://ruby-doc.org/core-1.9.3/Object.html#method-i-extend" title=""&gt;Object.extend&lt;/a&gt;. This then allows us to create an UnboundMethod that can be bound to a Boo instance even though it doesn&amp;#8217;t mixin the Foo module!&lt;/p&gt;
&lt;p&gt;Then all we have to do is bind our stolen method to the self variable in Boo and call that method.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Boo&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hi&lt;/span&gt;
    &lt;span class="c1"&gt;# temp class&lt;/span&gt;
    &lt;span class="n"&gt;pirate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Boo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# change execution context to this instance of Boo&lt;/span&gt;
    &lt;span class="n"&gt;stolen_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pirate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:hi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unbind&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# use our stolen method, prints &amp;quot;boo&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;stolen_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We can easily apply the same technique to our LinkedList implementation to pirate the map() function off of Enumerable. Notice how we can pass parameters to call just like a normal method:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pirate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;LinkedList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stolen_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pirate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:map&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unbind&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stolen_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2&gt;Generalizing&lt;/h2&gt;
&lt;p&gt;It would be quite tedious to have to pirate mulitple methods this way, but fortunately it&amp;#8217;s relatively easy to abstract this technique into a module method that we can mixin and call inside our LinkedList class:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;MethodPirate&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pirates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;the_module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;pirate_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;the_module&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stolen_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pirate_class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unbind&lt;/span&gt;

    &lt;span class="nb"&gt;send&lt;/span&gt; &lt;span class="ss"&gt;:define_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;stolen_method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LinkedList&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;MethodPirate&lt;/span&gt;
  &lt;span class="n"&gt;pirates&lt;/span&gt; &lt;span class="no"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:map&lt;/span&gt;
  &lt;span class="n"&gt;pirates&lt;/span&gt; &lt;span class="no"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:inject&lt;/span&gt;
  &lt;span class="c1"&gt;# rest of implementation &lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You do wan&amp;#8217;t to be careful here since this implementation isn&amp;#8217;t very performant, notice how we create a new object and closure everytime we call pirate(). So for production use you&amp;#8217;ll most likely want to cache the the generated classes/unbound methods.&lt;/p&gt;
&lt;h2&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;Hopefully you&amp;#8217;ve learned something about how to pirate methods in Ruby, metaprogramming and how it pirating methods from modules might be useful in situations where you only want to mixin parts of a module (or group of modules). Questions, comments or ideas feel free to post.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=8tBn7V5BVCE:QOxFFqQ_xP8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=8tBn7V5BVCE:QOxFFqQ_xP8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=8tBn7V5BVCE:QOxFFqQ_xP8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=8tBn7V5BVCE:QOxFFqQ_xP8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=8tBn7V5BVCE:QOxFFqQ_xP8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=8tBn7V5BVCE:QOxFFqQ_xP8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=8tBn7V5BVCE:QOxFFqQ_xP8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=8tBn7V5BVCE:QOxFFqQ_xP8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/8tBn7V5BVCE" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2012/01/21/Pirating-Ruby-Methods-For-Fun-And-Profit.html</feedburner:origLink></entry>
 
 <entry>
   <title>How To Write Your Own DSL</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/s-S1Qn-vagw/How-To-Write-Your-Own-DSL.html" />
   <updated>2012-01-08T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2012/01/08/How-To-Write-Your-Own-DSL</id>
   <content type="html">&lt;h1&gt;How To Write Your Own &lt;span class="caps"&gt;DSL&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;DLS&amp;#8217;s or Domain Specific Languages have become quite popular over the past few years. Perhaps you&amp;#8217;ve heard of DSLs before, but even if you haven&amp;#8217;t chances are you&amp;#8217;ve come into contact with one before. &lt;a href="http://http://rubyonrails.org/"&gt;Ruby On Rails&lt;/a&gt;, for example can be seen as a &lt;span class="caps"&gt;DSL&lt;/span&gt; for writing web apps, &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; is a &lt;span class="caps"&gt;DSL&lt;/span&gt; for manipulating the &lt;span class="caps"&gt;DOM&lt;/span&gt; and &lt;a href="http://en.wikipedia.org/wiki/SQL"&gt;&lt;span class="caps"&gt;SQL&lt;/span&gt;&lt;/a&gt; is a &lt;span class="caps"&gt;DSL&lt;/span&gt; for writing database queries.&lt;/p&gt;
&lt;h2&gt;Why Bother With DSLs?&lt;/h2&gt;
&lt;p&gt;DSLs are useful tools &amp;#8211; they allow us to easily express logic specific to a particular problem (domain) that would be otherwise difficult (or verbose) to write in another language. Usually this boils down that to using a grammar and syntax that more closely resembles the lexicon used by the target domain. For example a mathematician working with matrices doesn&amp;#8217;t think in loops, iterators or arrays but instead thinks in terms of vectors, dot products and transformations. Using a general purpose language with only arrays and iterators would require a fair amount of mental gymnastics for our mathematician as he would have to mentally translate between his problem domain (matrices) and the language he writes code in (ex. c++). Using a &lt;span class="caps"&gt;DSL&lt;/span&gt; designed for matrix operations would eliminate this mental translation while simultaneously providing code that is both more terse and (hopefully) less error prone.&lt;/p&gt;
&lt;h2&gt;Types of DSLs&lt;/h2&gt;
&lt;p&gt;DSLs come in two forms &amp;#8211; &lt;b&gt;external&lt;/b&gt; and &lt;b&gt;internal&lt;/b&gt;. External DSL&amp;#8217;s exist independently from any other language, &lt;span class="caps"&gt;SQL&lt;/span&gt; is a good example of an external &lt;span class="caps"&gt;DSL&lt;/span&gt;. Internal DSL&amp;#8217;s on the other hand live inside another programming language &amp;#8211; for example Rails is an internal &lt;span class="caps"&gt;DSL&lt;/span&gt; which is hosted within the Ruby programming language.&lt;/p&gt;
&lt;p&gt;Typically internal DSLs are easier to create but aren&amp;#8217;t as flexible as external DSL&amp;#8217;s. Internal DSL&amp;#8217;s need not worry about parsing or grammars but must conform to valid syntax within the host language (eg. all Rails code is valid Ruby syntax), conversely an external &lt;span class="caps"&gt;DSL&lt;/span&gt; can have any syntax its creator wishes at the cost more work to build a parser and grammar (again think &lt;span class="caps"&gt;SQL&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;One final thing to keep in mind is that internal DSLs allow you to take full advantage of the host language. Large applications often touch across multiple domains (database, business logic etc.) and passing data between multiple DSLs in a single host language tends to be much less of a headache than juggling multiple external DSLs &amp;#8211; which is why I prefer internal DSLs to external ones.&lt;/p&gt;
&lt;h2&gt;Making Your Own &lt;span class="caps"&gt;DSL&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;At first glance DSLs can be daunting &amp;#8211; but fear not they don&amp;#8217;t require magical unicorns or  superhuman powers. Actually they often turn out to be simple to create. This post will show you how to make your very own internal &lt;span class="caps"&gt;DSL&lt;/span&gt; using Ruby.&lt;/p&gt;
&lt;h3&gt;Picking a Domain&lt;/h3&gt;
&lt;p&gt;All DSLs start with a domain &amp;#8211; so let&amp;#8217;s pick something &amp;#8211; say Amazon&amp;#8217;s CloudWatch service. If you aren&amp;#8217;t familiar with CloudWatch it allows you to store, retrieve and aggregate metrics pertaining to servers you run in their cloud (EC2) service. Currently Amazon provides a command line tool (mon-get-stats) for querying CloudWatch, but it&amp;#8217;s fairly low level. Often times you want to aggregate metrics about servers running in multiple regions &amp;#8211; the current tool only allows you to query one region at a time, so for multi-regional metrics you&amp;#8217;re forced to manually merge the data. Having a nice &lt;span class="caps"&gt;DSL&lt;/span&gt; to help us view CloudWatch data across multiple regions would be great, so let&amp;#8217;s get to it!&lt;/p&gt;
&lt;h3&gt;Where to Start&lt;/h3&gt;
&lt;p&gt;Often when writing a new &lt;span class="caps"&gt;DSL&lt;/span&gt; it&amp;#8217;s helpful to start by imagining how we&amp;#8217;d like the ideal syntax to look. To have a good idea of what this ideal syntax might be, we should examin our requirements:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;We know we want to retrieve CloudWatch metrics from multiple regions.&lt;/li&gt;
	&lt;li&gt;We&amp;#8217;ll want to look at multiple metrics from the server&amp;#8217;s load balancer (abbreviated &lt;b&gt;elb&lt;/b&gt;) instead of a specific server instance (instances tend to be transient, sitting behind load balancers which are available).&lt;/li&gt;
	&lt;li&gt;CloudWatch stores data for up to two weeks, so our &lt;span class="caps"&gt;DSL&lt;/span&gt; will need a way of expressing what time frame we&amp;#8217;re interested in seeing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Something like the following would be a great start:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  &lt;span class="c1"&gt;# Assume DSL defined above&lt;/span&gt;

  &lt;span class="n"&gt;cloudwatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;CloudWatchClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;

  &lt;span class="c1"&gt;# returns our aggregated data&lt;/span&gt;
  &lt;span class="n"&gt;cloudwatch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;elb&lt;/span&gt;           &lt;span class="s2"&gt;&amp;quot;my-app-server&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;regions&lt;/span&gt;       &lt;span class="ss"&gt;:us_east_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:us_west_1&lt;/span&gt;
    &lt;span class="n"&gt;metrics&lt;/span&gt;       &lt;span class="ss"&gt;:request_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:other_metric&lt;/span&gt;
    &lt;span class="n"&gt;units&lt;/span&gt;         &lt;span class="ss"&gt;:count&lt;/span&gt; 
    &lt;span class="n"&gt;aggregation&lt;/span&gt;   &lt;span class="ss"&gt;:sum&lt;/span&gt;  
    &lt;span class="n"&gt;start_time&lt;/span&gt;    &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beginning_of_day&lt;/span&gt; 
    &lt;span class="n"&gt;period&lt;/span&gt;        &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Using our proposed syntax we instantiate an CloudWatchClient class whose stats() method serves as the entry point into our &lt;span class="caps"&gt;DSL&lt;/span&gt;. The above might seem a bit magical, but I promise it&amp;#8217;s nothing crazy. We simply execute the stats method and pass in a block (unexecuted function, similar to a lambda in other languages). All the special syntax inside the block will turn out to be just plain ol&amp;#8217; ruby method calls.&lt;/p&gt;
&lt;h3&gt;Implementing&lt;/h3&gt;
&lt;p&gt;Let&amp;#8217;s sketch out what our entry point class, CloudWatchClient will look like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CloudWatchClient&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;MergeData&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="c1"&gt;# authenticate with CloudWatch&amp;#39;s api&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# generate query parameters (heart of our DSL)&lt;/span&gt;
    &lt;span class="n"&gt;queries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="c1"&gt;# make cloudwatch api request(s)&lt;/span&gt;
    &lt;span class="n"&gt;get_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="c1"&gt;# merge the regional data &lt;/span&gt;
   &lt;span class="c1"&gt;# from MergeData module&lt;/span&gt;
    &lt;span class="n"&gt;merge_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# make necessary requests to CloudWatch&amp;#39;s api&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Following best practices for object-oriented programming, our client class has one responsibility &amp;#8211; making requests to the CloudWatch api. CloudWatch&amp;#8217;s api only allows querying for one metric and one region at a time, so we have to make multiple requests to the api and then merge them into a single data structure. Generating requests parameters and merging data are two separate tasks and thus live in their own classes/modules.&lt;/p&gt;
&lt;h3&gt;The DSLs heart&lt;/h3&gt;
&lt;p&gt;The task of merging regional data is delegated to a module called MergeData (left unimplemented) while the task of generating the query parameters is contained in the Query class. The Query class is really the heart of our &lt;span class="caps"&gt;DSL&lt;/span&gt; so I&amp;#8217;ll be focusing on that class and leave the nuts and bolts of making requests to the CloudWatch api along with merging the results as an exercise to the reader.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a first crack at our Query class that contains our &lt;span class="caps"&gt;DSL&lt;/span&gt; methods:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Query&lt;/span&gt; 
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# defaults&lt;/span&gt;
    &lt;span class="vi"&gt;@elb&lt;/span&gt;             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt; 
    &lt;span class="vi"&gt;@regions&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;us-east-1&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="vi"&gt;@metrics&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RequestCount&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="vi"&gt;@aggregation&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Average&amp;quot;&lt;/span&gt;
    &lt;span class="vi"&gt;@units&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Count&amp;quot;&lt;/span&gt;
    &lt;span class="vi"&gt;@start_time&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beginning_of_day&lt;/span&gt;
    &lt;span class="vi"&gt;@period&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;

    &lt;span class="nb"&gt;instance_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;to_cloudwatch_query_format&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;elb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@elb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;elb&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# varargs&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;regions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;regions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;regions&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@metrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;aggregation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aggreation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@aggregation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aggregation&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;units&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;units&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@units&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;units&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;period&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;period&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@period&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;period&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_cloudwatch_query_format&lt;/span&gt;
   &lt;span class="c1"&gt;# map data into format cloudwatch api understands&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Instance eval&lt;/h3&gt;
&lt;p&gt;Notice how our initialize method takes in a block and converts it to a proc with:  &lt;b&gt;instance_eval(&amp;amp;block)&lt;/b&gt;. This line is key to understanding the whole class. Ruby&amp;#8217;s instance eval takes a block and executes within the context of the class instance_eval was called from. This has &lt;b&gt;makes all of Query&amp;#8217;s methods callable in the block passed to Query&amp;#8217;s initialize method&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;So we can write:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="no"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;elb&lt;/span&gt;           &lt;span class="s2"&gt;&amp;quot;my-app-server&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;regions&lt;/span&gt;       &lt;span class="ss"&gt;:us_east_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:us_west_1&lt;/span&gt;
  &lt;span class="n"&gt;metrics&lt;/span&gt;       &lt;span class="ss"&gt;:request_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:other_metric&lt;/span&gt;
  &lt;span class="n"&gt;units&lt;/span&gt;         &lt;span class="ss"&gt;:count&lt;/span&gt; 
  &lt;span class="n"&gt;aggregation&lt;/span&gt;   &lt;span class="ss"&gt;:sum&lt;/span&gt;  
  &lt;span class="n"&gt;start_time&lt;/span&gt;    &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beginning_of_day&lt;/span&gt; 
  &lt;span class="n"&gt;period&lt;/span&gt;        &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Which really is just syntax sugar for regular method calls on the Query object, eg.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;elb&lt;/span&gt;           &lt;span class="s2"&gt;&amp;quot;my-app-server&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;regions&lt;/span&gt;       &lt;span class="ss"&gt;:us_east_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:us_west_1&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics&lt;/span&gt;       &lt;span class="ss"&gt;:request_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:other_metric&lt;/span&gt;
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;units&lt;/span&gt;         &lt;span class="ss"&gt;:count&lt;/span&gt; 
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aggregation&lt;/span&gt;   &lt;span class="ss"&gt;:sum&lt;/span&gt;  
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_time&lt;/span&gt;    &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beginning_of_day&lt;/span&gt; 
&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;period&lt;/span&gt;        &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Refactoring The Query Class&lt;/h3&gt;
&lt;p&gt;One issue with our Query class is that it&amp;#8217;s more verbose than it needs to be, we&amp;#8217;re defining one method per field &amp;#8211; ex elb, period, start_time. This gets worse as we add more fields to our &lt;span class="caps"&gt;DSL&lt;/span&gt;. Instead we can use Ruby&amp;#8217;s meta programming features to create a macro which creates these setters for us, like so:.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Query&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;method_names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;method_names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;send&lt;/span&gt; &lt;span class="ss"&gt;:define_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="nb"&gt;instance_variable_set&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;@&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; 
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;varags_setter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;method_names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;method_names&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;send&lt;/span&gt; &lt;span class="ss"&gt;:define_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="nb"&gt;instance_variable_set&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;@&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; 
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;setter&lt;/span&gt; &lt;span class="ss"&gt;:elb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:aggregation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:units&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:start_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:period&lt;/span&gt;
  &lt;span class="n"&gt;varargs_setter&lt;/span&gt; &lt;span class="ss"&gt;:metrics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:regions&lt;/span&gt; 

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# defaults&lt;/span&gt;
    &lt;span class="vi"&gt;@elb&lt;/span&gt;             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt; 
    &lt;span class="vi"&gt;@regions&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;us-east-1&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="vi"&gt;@metrics&lt;/span&gt;         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;RequestCount&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="vi"&gt;@aggregation&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Average&amp;quot;&lt;/span&gt;
    &lt;span class="vi"&gt;@units&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Count&amp;quot;&lt;/span&gt;
    &lt;span class="vi"&gt;@start_time&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beginning_of_day&lt;/span&gt;
    &lt;span class="vi"&gt;@period&lt;/span&gt;          &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;

    &lt;span class="nb"&gt;instance_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;to_cloudwatch_query_format&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_cloudwatch_query_format&lt;/span&gt;
   &lt;span class="c1"&gt;# map data into format cloudwatch api understands&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here we&amp;#8217;re adding two static methods on Query, setter and varags_setter. These methods are simple macros which creating setter methods automatically for us. You could also use Ruby&amp;#8217;s built in attr_accessor method here instead of rolling our own but that causes setter methods to be named like elb=() rather than elb() which is extra syntactic noise and you&amp;#8217;d have to deal with setters taking multiple parameters another way.&lt;/p&gt;
&lt;h2&gt;Putting It All Together&lt;/h2&gt;
&lt;p&gt;At this point we&amp;#8217;ve created our Query class which contains all of our &lt;span class="caps"&gt;DSL&lt;/span&gt; methods. The Query class calls instance_eval on the block passed to it, which gives us a nice syntax for the CloudWatch domain, by allowing Query&amp;#8217;s methods to be called inside the block. Then our CloudWatchClient class handles passing our configured queries off to the CloudWatch api finally the data is merged via the MergeData module.&lt;/p&gt;
&lt;p&gt;We can generalize what we&amp;#8217;ve done with our CloudWatch &lt;span class="caps"&gt;DSL&lt;/span&gt; to a blueprint for writing other DSL&amp;#8217;s in Ruby:&lt;/p&gt;
&lt;p&gt;1. Pick a problem domain that would benefit from a &lt;span class="caps"&gt;DSL&lt;/span&gt;&lt;br /&gt;
2. Invent an ideal syntax using your domain&amp;#8217;s lexicon &lt;br /&gt;
3. Create an entry point to your &lt;span class="caps"&gt;DSL&lt;/span&gt; (class or method) &lt;br /&gt;
4. Create a &lt;span class="caps"&gt;DSL&lt;/span&gt; class with method names corresponding to your chosen syntax &lt;br /&gt;
5. &lt;span class="caps"&gt;DSL&lt;/span&gt; class should accept a block that is instance_eval&amp;#8217;ed for syntax sugar&lt;br /&gt;
6. World Domination!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=s-S1Qn-vagw:V-Yyb2boPyc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=s-S1Qn-vagw:V-Yyb2boPyc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=s-S1Qn-vagw:V-Yyb2boPyc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=s-S1Qn-vagw:V-Yyb2boPyc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=s-S1Qn-vagw:V-Yyb2boPyc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=s-S1Qn-vagw:V-Yyb2boPyc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=s-S1Qn-vagw:V-Yyb2boPyc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=s-S1Qn-vagw:V-Yyb2boPyc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/s-S1Qn-vagw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2012/01/08/How-To-Write-Your-Own-DSL.html</feedburner:origLink></entry>
 
 <entry>
   <title>Get Your Company To Blog More</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/B2gduNLVTdw/Get-Your-Company-To-Blog-More.html" />
   <updated>2011-12-19T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2011/12/19/Get-Your-Company-To-Blog-More</id>
   <content type="html">&lt;h1&gt;Get Your Company To Blog More&lt;/h1&gt;
&lt;p&gt;Cross posted on the &lt;a href="http://dev.bizo.com"&gt;Bizo blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At &lt;a href="http://bizo.com"&gt;Bizo&lt;/a&gt; we try to blog fairly often. But writing blog posts with any degree of frequency at a startup is tough &amp;#8211; there are often ten other important tasks that needed to be done yesterday. Finding the time to sit down and write a post when you have features to build, code to review and the occasional meeting is difficult to say the least.&lt;/p&gt;
&lt;p&gt;We needed something that would encourage us to blog more frequently, and there&amp;#8217;s no better way to motivate a bunch of engineers than a game. So during our last Open Source Day we built a Blog Scoreboard that ranks authors based on the number of posts and comments they have. It&amp;#8217;s setup on our office big screen tv serving as constant reminder that &lt;a href="http://twitter.com/#!/ogrodnek/"&gt;Larry&lt;/a&gt; is by a landslide, the king of blogging. For a live demo of the scoreboard and to see just how much Larry is dominating us, checkout the live example below:&lt;/p&gt;
&lt;p&gt;Currently we just optimize towards the volume of posts so the points are currently assigned as: 10 points per blog post and 1 point per comment. The weighting scheme is intentionally naive due since this had to be built in a few hours and will undoubtably change as time goes on.&lt;/p&gt;
&lt;p&gt;The best part about our scoreboard is that it is an open source sinatra (ruby) app, and it works with any Blogger blog! All you have to do is edit a few lines of &lt;span class="caps"&gt;YAML&lt;/span&gt; and you&amp;#8217;ll have your very own big screen blog scoreboard. You can grab the source code and install instructions on github&lt;/p&gt;
&lt;p&gt;&lt;img src="/images/scoreboard_small.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog-leaderboard.heroku.com" class="medium purple pill bordered button"&gt;Live demo&lt;/a&gt; &lt;a href="https://github.com/jcarver989/blog-scoreboard" class="medium green pill bordered button"&gt;Get your own scoreboard&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=B2gduNLVTdw:NP18QCBE6Lo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=B2gduNLVTdw:NP18QCBE6Lo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=B2gduNLVTdw:NP18QCBE6Lo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=B2gduNLVTdw:NP18QCBE6Lo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=B2gduNLVTdw:NP18QCBE6Lo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=B2gduNLVTdw:NP18QCBE6Lo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=B2gduNLVTdw:NP18QCBE6Lo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=B2gduNLVTdw:NP18QCBE6Lo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/B2gduNLVTdw" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2011/12/19/Get-Your-Company-To-Blog-More.html</feedburner:origLink></entry>
 
 <entry>
   <title>The Ultimate Javascript Testing Setup</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/A_dsHp6-XFU/The-Ultimate-Javascript-Testing-Setup.html" />
   <updated>2011-12-11T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2011/12/11/The-Ultimate-Javascript-Testing-Setup</id>
   <content type="html">&lt;h1&gt;The Ultimate Javascript Testing Setup&lt;/h1&gt;
&lt;p&gt;Any programmer worth his (or her) salt knows that testing is an important part of software development. No I&amp;#8217;m not talking about mashing refresh on your browser and seeing if your code threw an exception &amp;#8211; I&amp;#8217;m talking about automated unit tests. Setting up unit tests for your front end JavaScript is actually pretty easy these days. You can pick from a multitude of drop in unit testing frameworks like &lt;a href="http://pivotal.github.com/jasmine"&gt;Jasmine&lt;/a&gt; or &lt;a href="http://code.google.com/p/google-js-test"&gt;Google&amp;#8217;s Js Test&lt;/a&gt; (but you really should use Jasmine).&lt;/p&gt;
&lt;p&gt;Loading your unit tests inside a standard browser works well for a short time on small projects with single developers. But when it comes time to integrate with the team and your build system (ex. Jenkins, Hudson, Cruise Control etc.) that approach isn&amp;#8217;t going to cut it &amp;#8211; for the ultimate testing setup you need to be able to execute your unit tests from the command line so your builds can pass/fail appropriately.&lt;/p&gt;
&lt;p&gt;What follows is what I consider to be the ultimate JavaScript test setup and is what I use everyday at &lt;a href="http://bizo.com"&gt;work&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Test Framework: Jasmine&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://pivotal.github.com/jasmine"&gt;Jasmine&lt;/a&gt; is by far my favorite unit testing framework. It combines a nice rspec like syntax along with facilities for testing asynchronous and delayed (timeout) functions. There have been many articles written &lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/testing-your-javascript-with-jasmine/"&gt;like this one&lt;/a&gt; which explain more about Jasmine&amp;#8217;s features and how to set it up, so I wont go into too much detail here. Suffice to say out of all the testing frameworks I&amp;#8217;ve tried (which is a lot) &amp;#8211; I like Jasmine the best by far.&lt;/p&gt;
&lt;h3&gt;Execution Environment: PhantomJS&lt;/h3&gt;
&lt;p&gt;For running tests on the command line I&amp;#8217;ve yet to find anything better than &lt;a href="http://phantomjs.org"&gt;PhantomJs&lt;/a&gt; which is a headless (~ non gui) fully-fledged webkit browser. Running a headless browser like PhantomJs gives you the benefit of testing in a real (webkit) browser on the command line with very, very good performance. For example I can run over 220 unit tests in around 1/10th of a second. You might also have heard of &lt;a href="http://zombie.labnotes.org/"&gt;Zombie.js&lt;/a&gt; but unfortunately Zombie.js isn&amp;#8217;t a complete browser and In my experience has a tendency to choke trying to execute valid JavaScript.&lt;/p&gt;
&lt;p&gt;Because of this I&amp;#8217;d recommend using PhantomJs over something like Zomebie.js. You can install PhantomJs for most platforms &lt;a href="http://code.google.com/p/phantomjs/wiki/Installation"&gt;here&lt;/a&gt; You&amp;#8217;ll probably also want to put phantomjs on your path for convenience&lt;/p&gt;
&lt;h3&gt;Hooking it all up: Phantom-Jasmine Bridge&lt;/h3&gt;
&lt;p&gt;Perhaps I&amp;#8217;ve sold you on using Jasmine and PhantomJs together &amp;#8211; but how do you set the two up and get them working together to bring you ultimate testing awesomeness? Lucky for you I&amp;#8217;ve already done the hard work.&lt;/p&gt;
&lt;p&gt;Assuming you already have PhantomJs installed all you have to do is download my &lt;a href="http://github.com/jcarver989/phantom-jasmine"&gt;phantom-jasmine&lt;/a&gt; repository over on Github. It comes with a Jasmine plugin along with a PhantomJs script that allows you to execute your suite of Jasmine tests directly on the command line with appropriate exit statuses and colored output! There&amp;#8217;s also some simple examples to help you get started.&lt;/p&gt;
&lt;p&gt;If you use the included TestRunner.html, running your tests becomes as easy as:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;phantomjs run_jasmine_test.coffee TestRunner.html
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you aren&amp;#8217;t starting from scratch and have an existing Jasmine Test Suite that you&amp;#8217;d like to use &amp;#8211; it&amp;#8217;s still easy, just add the following to your Jasmine initialization code in your html test runner:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="html"&gt;&lt;span class="c"&gt;&amp;lt;!-- JasmineTestRunner.html --&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- load this file, from phantom-jasmine repo --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;console-runner.js&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;// standard Jasmine init code&lt;/span&gt;
  &lt;span class="nx"&gt;jasmine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getEnv&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;addReporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TrivialReporter&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="c1"&gt;// what you need to add&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;console_reporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ConsoleReporter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;jasmine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getEnv&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;addReporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console_reporter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// make sure you add the above before execute() is called&lt;/span&gt;
  &lt;span class="nx"&gt;jasmine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getEnv&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="http://github.com/jcarver989/phantom-jasmine" class="medium purple bordered pill button"&gt;Get the ultimate test setup for yourself &amp;raquo;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=A_dsHp6-XFU:DuGkC4-I7uQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=A_dsHp6-XFU:DuGkC4-I7uQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=A_dsHp6-XFU:DuGkC4-I7uQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=A_dsHp6-XFU:DuGkC4-I7uQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=A_dsHp6-XFU:DuGkC4-I7uQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=A_dsHp6-XFU:DuGkC4-I7uQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=A_dsHp6-XFU:DuGkC4-I7uQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=A_dsHp6-XFU:DuGkC4-I7uQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/A_dsHp6-XFU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2011/12/11/The-Ultimate-Javascript-Testing-Setup.html</feedburner:origLink></entry>
 
 <entry>
   <title>Promises in Javascript/Coffeescript</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/S52JwdSv5Es/Futures-Promises-and-Deffered-Objects-in-JavaScript-Oh-My.html" />
   <updated>2011-12-10T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2011/12/10/Futures-Promises-and-Deffered-Objects-in-JavaScript-Oh-My</id>
   <content type="html">&lt;h1&gt;Promises in Javascript/Coffeescript&lt;/h1&gt;
&lt;p&gt;Cross posted on the &lt;a href="http://dev.bizo.com"&gt;Bizo Dev Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This happens often. You&amp;#8217;re humming along writing some awesome Javascript code. At first everything is neat and organized. Then you add a feature here, an &lt;span class="caps"&gt;AJAX&lt;/span&gt; call there and before your once lovely codebase has turned into callback spaghetti.&lt;/p&gt;
&lt;p&gt;One scenario where this can become particularly nasty is when you have an arbitrary number of asynchronous tasks, one of which cant run until all the others have completed. Suppose for example you are creating a page that displays information on your organization&amp;#8217;s engineering team and open source projects hosted on Github. This might require a few api calls to Github (eg. one to get the repositories, another to get the team members) that can be executed in parallel. We could just append the information to the &lt;span class="caps"&gt;DOM&lt;/span&gt; as each api call finishes, but it would be nice to avoid pieces of the site popping in at different times. Instead it would be ideal if we made the api calls to Github and only after both api calls had completed would we render the information to the &lt;span class="caps"&gt;DOM&lt;/span&gt;. The problem is that in Javascript trying to implement this can get quite messy.&lt;/p&gt;
&lt;h3&gt;A Bad Solution&lt;/h3&gt;
&lt;p&gt;The issue here is knowing when it is safe to execute the task that renders the Github information to the page. One strategy might be to store the results from each api call in an array and then wait for a set amount of time before drawing the page.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="coffeescript"&gt;&lt;span class="nv"&gt;results = &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="nx"&gt;githubApiCallOne&lt;/span&gt; &lt;span class="nf"&gt;(response) -&amp;gt;&lt;/span&gt; 
  &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;githubApiCallTwo&lt;/span&gt; &lt;span class="nf"&gt;(response) -&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;drawPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This turns out to be a poor solution as we can either end up waiting too little, in which case the program would fail or we could set the timeout too high making our users wait longer than necessary to load our page.&lt;/p&gt;
&lt;h3&gt;Promises to The Rescue&lt;/h3&gt;
&lt;p&gt;Fortunately there is a better way to implement our Github page. Using a construct called a Promise (sometimes called a Future) allows us to elegantly handle these types of situations. Using promises we can turn our code into something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="coffeescript"&gt;&lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;githubApiCallOne&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;githubApiCallTwo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;(apiCallOneData, apiCallTwoData) -&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;renderPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiCallOneData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;apiCallTwoData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The basic idea is that our async api calls will now return a promise object that functions much like an &lt;span class="caps"&gt;IOU&lt;/span&gt; &amp;#8211; they can&amp;#8217;t give us the results of the api call immediately but they (probably) can at some time in the future. The Promise.when method takes an arbitrary number of promise objects as parameters and then executes the callback in the &amp;#8220;then&amp;#8221; method once every promise passed to &amp;#8220;when&amp;#8221; has been completed.&lt;/p&gt;
&lt;p&gt;To do this, our api calls would have to be modified to return promise objects, which turns out to be trivial. Such an implementation might look like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="coffeescript"&gt;&lt;span class="nv"&gt;githubApiCallOne = &lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt;
  &lt;span class="nv"&gt;promise = &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;# async call&lt;/span&gt;
  &lt;span class="nx"&gt;ajaxGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/repositories&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;(repository_data) -&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;# fulfill the promise when async call completes&lt;/span&gt;
    &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;repository_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;

&lt;span class="nv"&gt;githubApiCallTwo = &lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt;
  &lt;span class="nv"&gt;promise = &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nx"&gt;ajaxGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/users&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;(user_data) -&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The githubApiCallOne and githubApiCallTwo make their ajax calls but return a promise object immediately. Then when the &lt;span class="caps"&gt;AJAX&lt;/span&gt; calls complete, they can fulfill the promise objects by calling &amp;#8220;complete&amp;#8221; and passing in their data. Once both promise objects have been fulfilled the callback passed to Promise.then is executed and we render the page.&lt;/p&gt;
&lt;h3&gt;With jQuery&lt;/h3&gt;
&lt;p&gt;The good news is if you&amp;#8217;re already using jQuery you get Promises for free. As of jQuery 1.5 all the $.ajax methods (eg. $.get, $.post etc) return promises which allows you to do this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="coffeescript"&gt;&lt;span class="nv"&gt;promise1 = &lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;http://foo.com&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;promise2 = &lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;http://boo.com&amp;quot;&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promise1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;promise2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nf"&gt;(promise1Result, promise2Result) -&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;# do something with the data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;What if I cant use jQuery?&lt;/h3&gt;
&lt;p&gt;Rolling a custom implementation of Promises isn&amp;#8217;t recommended for production code but might be necessary if you write a lot of 3rd party Javascript and/or just want to try it for fun. Here&amp;#8217;s a very basic implementation to get you started. Error handling, exceptions etc are left as an exercise to the reader.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="coffeescript"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;
  &lt;span class="vi"&gt;@when: &lt;/span&gt;&lt;span class="nf"&gt;(tasks...) -&amp;gt;&lt;/span&gt;
    &lt;span class="nv"&gt;num_uncompleted = &lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; 
    &lt;span class="nv"&gt;args = &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num_uncompleted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;promise = &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;task_id&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;(task_id) -&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt;
          &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="nx"&gt;num_uncompleted&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;
          &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;num_uncompleted&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;
    
  &lt;span class="nv"&gt;constructor: &lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt;
    &lt;span class="vi"&gt;@completed = &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="vi"&gt;@callbacks = &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="nv"&gt;complete: &lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt;
    &lt;span class="vi"&gt;@completed = &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="vi"&gt;@data = &lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;@callbacks&lt;/span&gt;
      &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;

  &lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;(callback) -&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;@completed&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;apply&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;@data&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="nx"&gt;@callbacks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Sharp eyed readers might notice that the code inside the for loop in the Promise.when method looks a bit strange. You might notice that I&amp;#8217;m wrapping the promise&amp;#8217;s &amp;#8220;then&amp;#8221; method call inside of a self executing function that passes in the task_id variable. This funkiness is actually required due to the way that closures work in Javascript. If you attempt to reference the task_id without the self executing closure, you&amp;#8217;ll actually get a reference to the task_id iterator instead of a copy &amp;#8211; which means by the time your &amp;#8220;then&amp;#8221; methods execute the loop will have finished iterating and all the task_ids will share the same value! To get around this you have to create a new scope and pass in the iterator so we end up with a copy of the value instead of a reference.&lt;/p&gt;
&lt;p&gt;And Finally an example using the supplied Promise class to prove it works:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="coffeescript"&gt;&lt;span class="nv"&gt;delay = &lt;/span&gt;&lt;span class="nf"&gt;(string) -&amp;gt;&lt;/span&gt;
  &lt;span class="nv"&gt;promise = &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt; 
    &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;complete&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;

&lt;span class="nv"&gt;logEverything = &lt;/span&gt;&lt;span class="nf"&gt;(fooData, barData, bazData) -&amp;gt;&lt;/span&gt; 
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="nx"&gt;fooData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;barData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;bazData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;onload = &lt;/span&gt;&lt;span class="nf"&gt;() -&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;baz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="nx"&gt;logEverything&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=S52JwdSv5Es:eZmoqE5XnAE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=S52JwdSv5Es:eZmoqE5XnAE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=S52JwdSv5Es:eZmoqE5XnAE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=S52JwdSv5Es:eZmoqE5XnAE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=S52JwdSv5Es:eZmoqE5XnAE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=S52JwdSv5Es:eZmoqE5XnAE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=S52JwdSv5Es:eZmoqE5XnAE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=S52JwdSv5Es:eZmoqE5XnAE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/S52JwdSv5Es" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2011/12/10/Futures-Promises-and-Deffered-Objects-in-JavaScript-Oh-My.html</feedburner:origLink></entry>
 
 <entry>
   <title>How to Write Large JavaScript Projects</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/K1RJauJGwLY/how-to-organize-large-javascript-projects.html" />
   <updated>2011-12-04T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2011/12/04/how-to-organize-large-javascript-projects</id>
   <content type="html">&lt;h1&gt;How to Write Large JavaScript Projects&lt;/h1&gt;
&lt;p&gt;Client-side Javascript can have a nasty tendency to balloon out of control in a large project. Since Javascript has many quirks and no built in module or dependency system things can quickly become a tangled, bug-ridden mess if you aren&amp;#8217;t careful. Over the past year and change I&amp;#8217;ve had the opportunity to work on several large JavaScript projects at &lt;a href="http://bizo.com"&gt;Bizo&lt;/a&gt; &amp;#8211; and these are what I have found to be best practices.&lt;/p&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;It should be obvious that testing is by far the most important thing to pay attention to when working on a large project &amp;#8211; especially with JavaScript due to browser idiosyncrasies. You can get by without tests on small personal projects but for high quality production code &amp;#8211; testing is a must.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve found that a combination of fast unit tests using &lt;a href="http://www.phantomjs.org/"&gt;PhantomJs&lt;/a&gt; and &lt;a href="http://pivotal.github.com/jasmine/"&gt;Jasmine&lt;/a&gt; for development plus a suite of cross browser Selenium tests is ideal. While you&amp;#8217;re coding you can continuously run your unit tests, which with my setup takes less then 1/10th of a second for 200+ tests. Then when it&amp;#8217;s time to deploy you run the entire suite of (slower) selenium tests. This way you maintain a high quality test suite without disrupting your normal development cycle. I&amp;#8217;d also highly recommend checking out &lt;a href="http://saucelabs.com/"&gt;SauceLabs&lt;/a&gt; &amp;#8211; they allow you to run cross browser Selenium tests, which means you don&amp;#8217;t have to fuss with multiple IE vms. SauceLabs even gives you 200 minutes a month of test time free, which should be more than enough for most users needs.&lt;/p&gt;
&lt;h3&gt;Modules&lt;/h3&gt;
&lt;p&gt;Most front end developers will already be familiar with the module pattern, but if you aren&amp;#8217;t you should familiarize yourself with it. Basically we wrap a group of related functions/objects in a self executing function that returns a &amp;#8220;public&amp;#8221; object. This allows us to only occupy one symbol in the global namespace (our module&amp;#8217;s name) rather than one per function/variable. Here&amp;#8217;s a basic implementation of the module pattern with both private and public components:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;private_variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;private_function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;private_variable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;public_interface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;public_interface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public_function&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;private_function&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;public_interface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;You should make use of modules throughout your project(s) to reduce the chance of accidentally overwriting variables.&lt;/p&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;Modules are great, but as they grow eventually you&amp;#8217;ll want to begin to split up a module into multiple files. Smaller files are easier to reason about and easier to test in isolation. Ideally you&amp;#8217;d have one file per object/group of related functions. But as soon as we begin splitting up modules into multiple files we have to manage dependencies. For example if we had a charting module called &amp;#8220;Charts&amp;#8221; we might split this up into files LineChart, BarChart and AbstractChart. Now suppose that LineChart and BarChart both depend on AbstractChart &amp;#8211;  unfortunately Javascript doesn&amp;#8217;t a means to resolve this dependency. Instead we have to handle this ourselves or via a 3rd party tool.&lt;/p&gt;
&lt;p&gt;One option is we could simply arrange the order in which we include scripts like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;abstract_chart.js&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/script&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;line_chart.js&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/script&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bar_chart.js&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Sadly, this approach wont scale as we add more files to our project manging dependencies like this becomes a headache at best and an head-splitting migraine that makes you want to kill kittens at worst.&lt;/p&gt;
&lt;p&gt;Another approach is to use a script loader like &lt;a href="http://requirejs.org/"&gt;RequireJS&lt;/a&gt; which will handle loading modules for us. This works well if you only have a hand-full of files to load &amp;#8211; but in a large project a single module could have upwards of ten files, multiply ten by the number of modules you have and it&amp;#8217;s easy to see that this doesn&amp;#8217;t scale nicely either.&lt;/p&gt;
&lt;p&gt;Instead, I&amp;#8217;ve found the best way to manage dependencies for production is to resolve them in a compile step, such that each module ends up as a single JavaScript file concatenated in dependency order. Using our previous example of the &amp;#8220;Charts&amp;#8221; module we would end up with a &amp;#8220;Charts.js&amp;#8221; file whose contents might look like this: AbstractChart + BarChart + LineChart. This allows you to test everything in isolation and resolve dependencies in a way that still plays nicely with manual script insertion or RequireJs.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve written a ruby gem, &lt;a href="http://github.com/jcarver989/dependence.js"&gt;Dependence.js&lt;/a&gt; that makes this kind of dependency resolution for JavaScript and/or CoffeeScript trivial. In the Charts example all you would have to do is this:&lt;/p&gt;
&lt;p&gt;AbstractChart.js&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;AbstractChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// code ..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;BarChart.js&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="c1"&gt;// @import AbstractChart.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;BarChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AbstractChart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// code ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;LineChart.js&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="javascript"&gt;&lt;span class="c1"&gt;// @import AbstractChart.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;LineChart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AbstractChart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// code ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Build Everything&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="bash"&gt;dependence path_to_src_dir -o output_dir
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;What about Backbone, Spine, jQuery and other frameworks?&lt;/h3&gt;
&lt;p&gt;It goes without saying that if you&amp;#8217;re able to use a nice framework to abstract away some common functionality you want to use in your projects &amp;#8211; you should. Working at &lt;a href="http://bizo.com"&gt;Bizo&lt;/a&gt; most of our code runs on 3rd part websites with an enormous amount of variation in the environment our tags are loaded in &amp;#8211; hence the majority of my experience has been writing raw JavaScript. But don&amp;#8217;t fret there have been many, many blog posts covering how to use these frameworks and all of the above principles still apply.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s it for now. Thoughts, comments or suggestions for important things to consider when building large JavaScript projects please share!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=K1RJauJGwLY:0ZlO-fBVSw4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=K1RJauJGwLY:0ZlO-fBVSw4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=K1RJauJGwLY:0ZlO-fBVSw4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=K1RJauJGwLY:0ZlO-fBVSw4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=K1RJauJGwLY:0ZlO-fBVSw4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=K1RJauJGwLY:0ZlO-fBVSw4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=K1RJauJGwLY:0ZlO-fBVSw4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=K1RJauJGwLY:0ZlO-fBVSw4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/K1RJauJGwLY" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2011/12/04/how-to-organize-large-javascript-projects.html</feedburner:origLink></entry>
 
 <entry>
   <title>Kickass HTML5 SVG Charts</title>
   <link href="http://feedproxy.google.com/~r/softwarebyjosh/~3/7pDuCmHeKlU/kickass-html5-svg-charts.html" />
   <updated>2011-12-03T00:00:00-08:00</updated>
   <id>http://jcarver989.github.com/2011/12/03/kickass-html5-svg-charts</id>
   <content type="html">&lt;h1&gt;Kickass HTML5 &lt;span class="caps"&gt;SVG&lt;/span&gt; Charts&lt;/h1&gt;
&lt;h2 class="date"&gt;December 03, 2011&lt;/h2&gt;
&lt;div id="chart1" style="width: 550px; height: 200px;"&gt;&lt;/div&gt;
&lt;p&gt;Let&amp;#8217;s face it, most charting libraries suck. Often times the default charts look awful. You need to set seemingly hundreds of options to get something that looks halfway decent. Other times the api is wonky. You might have to do extra work to 0 pad or transform data into an intermediate data structure (I&amp;#8217;m looking at you Google Visualizations).&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s 2011, charts should look good by default, not require developers to do extra data transformation and (gasp!) work in IE. But after looking around for a charting library that could do all three of these things (well) &amp;#8211; I was left found wanting.&lt;/p&gt;
&lt;p&gt;Lacking a good solution, I decided to write my own open-source charting library &amp;#8211; Raphy Charts. Raphy Charts draws vector charts in &lt;span class="caps"&gt;SVG&lt;/span&gt; and is built ontop of the excellent &lt;a href="http://raphaeljs.com/"&gt;Raphael&lt;/a&gt; &amp;#8211; it even works in IE due to Raphael&amp;#8217;s fallback support of &lt;span class="caps"&gt;VML&lt;/span&gt;. Time series (line, bar) charts, smoothing, tooltips, axis labeling, and sparklines are all currently supported, and I have many more features planned for the near future.&lt;/p&gt;
&lt;p&gt;The best part is Raphy Charts is open source and super easy to setup.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://jcarver989.github.com/raphy-charts" class="micro bordered pill green button"&gt;Get Raphy Charts&lt;/a&gt;&lt;/p&gt;
&lt;script src="https://raw.github.com/DmitryBaranovskiy/raphael/master/raphael-min.js"&gt;&lt;/script&gt;&lt;script src="https://raw.github.com/jcarver989/raphy-charts/master/compiled/charts.min.js"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;
  var create_date = function(day) {
    var d;
    d = new Date();
    return new Date(d.getFullYear(), d.getMonth(), day + 1);
  };

  var create_exponential_points = function() {
    var i, _results;
    _results = [];
    for (i = 0; i &lt;= 25; i++) {
      _results.push([create_date(i), i * 4.]);
    }
    return _results;
  };

  var create_squared_points = function() {
    var i, _results;
    _results = [];
    for (i = 0; i &lt;= 25; i++) {
      _results.push([create_date(i), i * (i - 1)]);
    }
    return _results;
  };

c = new Charts.LineChart('chart1', {
  show_y_labels: false
});

c.add_line ({ 
  // 2d array of x,y values ex:  [[1,1], [2,3], [3,20]]
  // OR x values may be dates: [[new Date(),100]...]
  data: create_squared_points() 
});

c.add_line({
  data: create_exponential_points(), 
  options: {
    line_color : "#55bb00",
    area_color : "#55bb00",
    dot_color  :  "#55bb00"
  }
});

c.draw();
&lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=7pDuCmHeKlU:CfffrQas47w:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=7pDuCmHeKlU:CfffrQas47w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=7pDuCmHeKlU:CfffrQas47w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=7pDuCmHeKlU:CfffrQas47w:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=7pDuCmHeKlU:CfffrQas47w:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=7pDuCmHeKlU:CfffrQas47w:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/softwarebyjosh?a=7pDuCmHeKlU:CfffrQas47w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/softwarebyjosh?i=7pDuCmHeKlU:CfffrQas47w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/softwarebyjosh/~4/7pDuCmHeKlU" height="1" width="1"/&gt;</content>
 <feedburner:origLink>http://jcarver989.github.com/2011/12/03/kickass-html5-svg-charts.html</feedburner:origLink></entry>
 
 
</feed>

