<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Adventures in JavaScript Development]]></title>
  <link href="http://rmurphey.com/atom.xml" rel="self"/>
  <link href="http://rmurphey.com/"/>
  <updated>2012-04-12T16:37:07-04:00</updated>
  <id>http://rmurphey.com/</id>
  <author>
    <name><![CDATA[Rebecca Murphey]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[A Baseline for Front-End Developers]]></title>
    <link href="http://rmurphey.com/blog/2012/04/12/a-baseline-for-front-end-developers/"/>
    <updated>2012-04-12T11:30:00-04:00</updated>
    <id>http://rmurphey.com/blog/2012/04/12/a-baseline-for-front-end-developers</id>
    <content type="html"><![CDATA[<p>I wrote a README the other day for a project that I&#8217;m hoping other developers will look at and learn from, and as I was writing it, I realized that it was the sort of thing that might have intimidated the hell out of me a couple of years ago, what with its casual mentions of Node, npm, Homebrew, git, tests, and development and production builds.</p>

<p>Once upon a time, editing files, testing them locally (as best as we could, anyway), and then FTPing them to the server was the essential workflow of a front-end dev. We measured our mettle based on our ability to wrangle IE6 into submission or achieve pixel perfection across browsers. Many members of the community &#8211; myself included &#8211; lacked traditional programming experience. HTML, CSS, and JavaScript &#8211; usually in the form of jQuery &#8211; were self-taught skills.</p>

<p>Something has changed in the last couple of years. Maybe it&#8217;s the result of people starting to take front-end dev seriously, maybe it&#8217;s browser vendors mostly getting their shit together, or maybe it&#8217;s front-end devs &#8211; again, myself included &#8211; coming to see some well-established light about the process of software development.</p>

<p>Whatever it is, I think we&#8217;re seeing the emphasis shift from valuing trivia to valuing tools. There&#8217;s a new set of baseline skills required in order to be successful as a front-end developer, and developers who don&#8217;t meet this baseline are going to start feeling more and more left behind as those who are sharing their knowledge start to assume that certain things go without saying.</p>

<p>Here are a few things that <em>I</em> want to start expecting people to be familiar with, along with some resources you can use if you feel like you need to get up to speed. (Thanks to Paul Irish, Mike Taylor, Angus Croll, and Vlad Filippov for their contributions.)</p>

<h2>JavaScript</h2>

<p>This might go without saying, but simply knowing a JavaScript library isn&#8217;t sufficient anymore. I&#8217;m not saying you need to know how to implement all the features of a library in plain JavaScript, but you should know when a library is actually required, and be capable of working with plain old JavaScript when it&#8217;s not.</p>

<p>That means that you&#8217;ve read <a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742">JavaScript: The Good Parts</a> &#8211; hopefully more than once. You understand data structures like objects and arrays; functions, including how and why you would <code>call</code> and <code>apply</code> them; working with prototypal inheritance; and managing the asynchronicity of it all.</p>

<p>If your plain JS fu is weak, here are some resources to help you out:</p>

<ul>
<li><a href="http://eloquentjavascript.net">Eloquent Javascript</a>: A wonderful book (also available in print) that takes you back to JavaScript basics</li>
<li><a href="https://github.com/rmurphey/js-assessment">A Test-Driven JS Assessment</a>: A set of failing tests that cover various JavaScript topics; can you write code to make the tests pass?</li>
<li><a href="http://paulirish.com/2010/10-things-i-learned-from-the-jquery-source/">10 things I learned from the jQuery Source</a> is an oldie but goodie from Paul Irish that shows what you can learn by reading other people&#8217;s code.</li>
</ul>


<h2>Git (and a Github account)</h2>

<p>If you&#8217;re not on Github, you&#8217;re essentially unable to participate in the rich open-source community that has arisen around front-end development technologies. Cloning a repo to try it out should be second-nature to you, and you should understand how to <a href="http://nvie.com/posts/a-successful-git-branching-model/">use branches on collaborative projects</a>.</p>

<p>Need to boost your git skills?</p>

<ul>
<li><a href="http://help.github.com/">help.github.com</a></li>
<li><a href="http://help.github.com/git-cheat-sheets/">Github git cheat sheet</a></li>
<li><a href="http://cheat.errtheblog.com/s/git">More cheat sheet</a></li>
<li><a href="http://pinboard.in/u:rmurphey/t:git/">More git links</a></li>
</ul>


<h2>Modularity, dependency management, and production builds</h2>

<p>The days of managing dependencies by throwing one more script or style tag on the page are long gone. Even if you haven&#8217;t been able to incorporate great tools like <a href="http://requirejs.org">RequireJS</a> into your workflow at work, you should find time to investigate them in a personal project or in a project like <a href="https://github.com/backbone-boilerplate/backbone-boilerplate">Backbone Boilerplate</a>, because the benefits they convey are huge. RequireJS in particular lets you develop with small, modular JS and CSS files, and then concatenates and minifies them via its optimization tool for production use.</p>

<p>Skeptical of AMD? That&#8217;s no excuse to be doing nothing. At the very least, you should be aware of tools like <a href="https://github.com/mishoo/UglifyJS">UglifyJS</a> or <a href="https://developers.google.com/closure/compiler/">Closure Compiler</a> that will intelligently minify your code, and then concatenate those minified files prior to production.</p>

<p>If you&#8217;re writing plain CSS &#8211; that is, if you&#8217;re not using a preprocessor like Sass or Stylus &#8211; RequireJS can help you keep your CSS files modular, too. Use <code>@import</code> statements in a base file to load dependencies for development, and then run the RequireJS <a href="http://requirejs.org/docs/optimization.html#onecss">optimizer</a> on the base file to create a file built for production.</p>

<h2>In-Browser Developer Tools</h2>

<p>Browser-based development tools have improved tremendously over the last couple of years, and they can dramatically improve your development experience if you know how to use them. (Hint: if you&#8217;re still using <code>alert</code> to debug your code, you&#8217;re wasting a lot of time.)</p>

<p>You should probably find one browser whose developer tools you primarily use &#8211; I&#8217;m partial to <a href="https://developers.google.com/chrome-developer-tools/">Google Chrome&#8217;s Developer Tools</a> these days &#8211; but don&#8217;t dismiss the tools in other browsers out of hand, because they are constantly adding useful features based on developer feedback. Opera&#8217;s <a href="http://my.opera.com/dragonfly/blog/">Dragonfly</a> in particular has some features that make its developer tools stand out, such as an (experimental) CSS profiler, customizable keyboard shortcuts, remote debugging without requiring a USB connection, and the ability to save and use custom color palettes.</p>

<p>If your understanding of browser dev tools is limited, <a href="http://fixingthesejquery.com/#slide1">Fixing these jQuery</a> is a great (and not particularly jQuery-centric) overview of debugging, including how to do <a href="https://developers.google.com/chrome-developer-tools/docs/scripts-breakpoints">step debugging</a> &#8211; a life-altering thing to learn if you don&#8217;t already know it.</p>

<h2>The command line</h2>

<p>Speaking of the command line, being comfortable with it is no longer optional &#8211; you&#8217;re missing out on way too much if you&#8217;re not ready to head over to a terminal window and get your hands dirty. I&#8217;m not saying you have to do <em>everything</em> in the terminal &#8211; I won&#8217;t take your git GUI away from you even though I think you&#8217;ll be better off without it eventually &#8211; but you should absolutely have a terminal window open for whatever project you&#8217;re working on. There are a few command line tasks you should be able to do without thinking:</p>

<ul>
<li><code>ssh</code> to log in to another machine or server</li>
<li><code>scp</code> to copy files to another machine or server</li>
<li><code>ack</code> or <code>grep</code> to find files in a project that contain a string or pattern</li>
<li><code>find</code> to locate files whose names match a given pattern</li>
<li><code>git</code> to do at least basic things like <code>add</code>, <code>commit</code>, <code>status</code>, and <code>pull</code></li>
<li><code>brew</code> to use Homebrew to install packages</li>
<li><code>npm</code> to install Node packages</li>
<li><code>gem</code> to install Ruby packages</li>
</ul>


<p>If there are commands you use frequently, edit your <code>.bashrc</code> or <code>.profile</code> or <code>.zshrc</code> or whatever, and create an <a href="http://tldp.org/LDP/abs/html/aliases.html">alias</a> so you don&#8217;t have to type as much. You can also add aliases to your <code>~/.gitconfig</code> file. Gianni Chiappetta&#8217;s <a href="https://github.com/gf3/dotfiles">dotfiles</a> are an excellent inspiration for what&#8217;s possible.</p>

<p><em>Note: If you&#8217;re on Windows, I don&#8217;t begin to know how to help you, aside from suggesting <a href="http://www.cygwin.com/">Cygwin</a>. Right or wrong, participating in the open-source front-end developer community is materially more difficult on a Windows machine. On the bright side, MacBook Airs are cheap, powerful,  and ridiculously portable, and there&#8217;s always Ubuntu or another *nix.</em></p>

<h2>Client-side templating</h2>

<p>It wasn&#8217;t so long ago that it was entirely typical for servers to respond to XHRs with a snippet of HTML, but sometime in the last 12 to 18 months, the front-end dev community saw the light and started demanding pure data from the server instead. Turning that data into HTML ready to be inserted in the DOM can be a messy and unmaintainable process if it&#8217;s done directly in your code. That&#8217;s where <a href="http://www.slideshare.net/garann/using-templates-to-achieve-awesomer-architecture">client-side templating libraries</a> come in: they let you maintain templates that, when mixed with some data, turn into a string of HTML. Need help picking a templating tool? Garann Means&#8217; <a href="http://garann.github.com/template-chooser/">template chooser</a> can point you in the right direction.</p>

<h2>CSS preprocessors</h2>

<p>Paul Irish <a href="https://twitter.com/#!/paul_irish/status/188329390822801409">noted</a> the other day that we&#8217;re starting to see front-end devs write code that&#8217;s very different from what ends up in production, and code written with CSS preprocessors is a shining example of this. There&#8217;s still a vocal crowd that feels that pure CSS is the only way to go, but they&#8217;re <a href="http://www.stuffandnonsense.co.uk/blog/about/less">starting to come around</a>. These tools give you features that arguably should be in CSS proper by now &#8211; variables, math, logic, mixins &#8211; and they can also help smooth over the CSS property prefix mess.</p>

<h2>Testing</h2>

<p>One of the joys of writing modular, loosely coupled code is that your code becomes vastly easier to test, and with tools like <a href="https://github.com/cowboy/grunt">Grunt</a>, setting up a project to include tests has never been easier. Grunt comes with QUnit integration, but there are a host of testing frameworks that you can choose from &#8211; <a href="https://github.com/pivotal/jasmine/wiki">Jasmine</a> and <a href="http://visionmedia.github.com/mocha/">Mocha</a> are a couple of my current favorites &#8211; depending on your preferred style and the makeup of the rest of your stack.</p>

<p>While testing is a joy when your code is modular and loosely coupled, testing code that&#8217;s not well organized can be somewhere between difficult and impossible. On the other hand, forcing yourself to write tests &#8211; perhaps before you even write the code &#8211; will help you organize your thinking <em>and</em> your code. It will also let you refactor your code with greater confidence down the line.</p>

<ul>
<li>A short <a href="http://vimeo.com/20457625">screencast</a> I recorded about testing your jQuery with Jasmine.</li>
<li>An example of <a href="https://github.com/cowboy/jquery-bbq/blob/master/unit/unit.js">unit tests</a> on the jquery-bbq plugin.</li>
</ul>


<h2>Process automation</h2>

<p>Grunt&#8217;s ability to set up a project with built-in support for unit tests is one example of process automation. The reality of front-end development is that there&#8217;s a whole lot of repetitive stuff we have to do, but as a friend once told me, a good developer is a lazy developer: as a rule of thumb, if you find yourself doing the same thing three times, it&#8217;s time to automate it.</p>

<p>Tools like <code>make</code> have been around for a long time to help us with this, but there&#8217;s also <code>rake</code>, <code>grunt</code>, and others. Learning a language other than JavaScript can be extremely helpful if you want to automate tasks that deal with the filesystem, as Node&#8217;s async nature can become a real burden when you&#8217;re just manipulating files. There are lots of task-specific automation tools, too &#8211; tools for deployment, build generation, code quality assurance, and more.</p>

<h2>Code quality</h2>

<p>If you&#8217;ve ever been bitten by a missing semicolon or an extra comma, you know how much time can be lost to subtle flaws in your code. That&#8217;s why you&#8217;re running your code through a tool like <a href="http://www.jshint.com/">JSHint</a>, right? It&#8217;s <a href="http://www.jshint.com/options/">configurable</a> and has lots of ways to integrate it into your <a href="http://www.jshint.com/platforms/">editor or build process</a>.</p>

<h2>The fine manual</h2>

<p>Alas, there is no manual for front-end development, but <a href="https://developer.mozilla.org/en-US/">MDN</a> comes pretty close. Good front-end devs know to prefix any search engine query with <code>mdn</code> &#8211; for example, <code>mdn javascript arrays</code> &#8211; in order to avoid the for-profit plague that is w3schools.</p>

<h2>The End</h2>

<p>As with anything, reading about these things won&#8217;t make you an expert, or even moderately skilled &#8211; the only surefire way to get better at a thing is to <a href="http://rmurphey.com/blog/2011/05/20/getting-better-at-javascript/">do that thing</a>. Good luck.</p>

<p>Update: Check out the conversation on <a href="http://news.ycombinator.com/item?id=3833200">Hacker News</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Greenfielding]]></title>
    <link href="http://rmurphey.com/blog/2012/04/10/greenfielding/"/>
    <updated>2012-04-10T12:19:00-04:00</updated>
    <id>http://rmurphey.com/blog/2012/04/10/greenfielding</id>
    <content type="html"><![CDATA[<p>I&#8217;m officially one-third of the way through my self-imposed month of unemployment before I join <a href="http://bocoup.com">Bocoup</a> at the beginning of May, and I&#8217;ve been spending most of what would normally be my working hours on a small demo to support talks at <a href="http://2012.front-trends.com/">conferences</a> I will be <a href="http://backboneconf.com/">speaking at</a> this <a href="http://2012.texasjavascript.com/">summer</a>. It&#8217;s just a <a href="https://github.com/rmurphey/srchr-demo">little app</a> that searches various services, and displays the results &#8211; so simple that, when I showed it to Melissa, she helpfully asked why I wouldn&#8217;t just use Google.</p>

<p>It&#8217;s been about 18 months since I last got to start a project from scratch &#8211; in that case, the codebase that became <a href="http://mulberry.toura.com">Mulberry</a> &#8211; but even then, I didn&#8217;t have control over the full stack of technologies, just the JavaScript side of things. Over the course of my time on that project, I came to be extremely familiar with Dojo, fairly competent with Jasmine, decently comfortable with Ruby and its go-to simple server Sinatra, and somewhat conversational in Sass.</p>

<p>I spent most of my time on that project working with technologies with which I was already pretty comfortable. Interactions with new technologies came in dribs and drabs (except for that one time I decided to test my Ruby skills by rewriting our entire build process), and all of my learning was backed up by a whole lot of institutional knowledge.</p>

<p>The consulting world, of course, is a wee bit different: you interact frequently with new technologies, and you never know what a client might ask you to do. Learning comes in bursts, and the ability to quickly come up to speed with a technology is imperative. On a six-week project, you can&#8217;t spend the first 40 hours getting your bearings.</p>

<p>Even though I spent three years as a consultant, returning to that world of constant learning was feeling a tad intimidating. And so for this project, I decided to make a point of leaving that comfort zone, and intentionally chose technologies &#8211; Node, Bootstrap, Backbone, Mocha, RequireJS &#8211; that I hadn&#8217;t really had a chance to work with in depth (or at all).</p>

<h2>On Learning</h2>

<p>Greenfield projects are few and far between, and it&#8217;s easy to get in a rut by sticking with the tools you already know. Some of my most exciting times at Toura weren&#8217;t when I was writing JavaScript, but rather when I was learning how to talk to the computer in a whole new language. Greenfielding a personal project is a special treat &#8211; it never really has to be &#8220;finished,&#8221; and no one&#8217;s going to be mad at you if it turns out you made a shitty choice, so you&#8217;re free to try things that are less of a sure thing than they would need to be if you were getting paid.</p>

<p>Speaking personally, it can also be a little intimidating to learn a new thing because learning often involves asking for help, and asking for help requires admitting that I don&#8217;t already know how to do the thing that people might expect I already know how to do.</p>

<p>Sometimes the thing that gets in the way of starting a new learning project is actually the fear that I will get stuck. What does it mean if the person who talks at conferences about principles code organization can&#8217;t figure out how best to structure a particular app with Backbone? What does it mean if the person who&#8217;s been encouraging people to build their JavaScript can&#8217;t get RequireJS to generate a proper build? What will I say to <a href="http://blog.izs.me/">Isaac</a>, now that he is standing in front of me and introducing himself, when I have not in fact spent any quality time with Node prior to this past weekend?</p>

<p>Lucky for me, it turns out that all of this is mostly in my head. While I often preface my questions with a small dose of humility and embarrassment, it turns out that well articulated questions are usually greeted with thoughtful and helpful answers. If anything, I&#8217;m trying to be more communicative about the learning that I do, because I think it&#8217;s important that people feel comfortable acknowledging that they used to not know a certain thing, and now they do. I also try to gently remind people that just because they have known something for months or years doesn&#8217;t mean they should look down upon the person enthusiastically blogging about it today.</p>

<p>On that note &#8230; here&#8217;s what&#8217;s new to me these past couple of weeks :)</p>

<h2>Twitter Bootstrap</h2>

<p>I&#8217;ve written a lot of demo apps, and while my coding style has changed over the years, one thing has remained constant: they all look fairly terrible. In theory, we&#8217;re all smart enough to know that what a demo looks like doesn&#8217;t have any bearing on what it explains, but in reality a good-looking demo is simply more compelling, if only because the viewer isn&#8217;t distracted by the bad design.</p>

<p>With this in mind, I decided to give <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a> a try. When I first arrived at the site, I started looking for docs about how to set it up, but it turns out that I vastly overestimated Bootstrap&#8217;s complexity. Drop a style tag into your page (and, optionally, another style tag for the responsive CSS), look at the <a href="http://twitter.github.com/bootstrap/examples.html">examples</a>, and start writing your markup.</p>

<p>What I really loved is that there were patterns for everything I needed, and those patterns were easy to follow and implement. Within an hour or so I had a respectable-looking HTML page with markup that didn&#8217;t seem to suck &#8211; that is, it looked good <em>and</em> it was a decent starting point if I ever wanted to apply a custom design.</p>

<h2>Node</h2>

<p>If you&#8217;ve ever talked to me about Node, you know that I have pretty mixed feelings about it &#8211; some days I feel like the people writing JavaScript in the browser really would have benefited if the people who have gravitated to Node had stuck around to invest their collective smarts in the world where 99% of JavaScript is still written. But that doesn&#8217;t really have anything to do with Node the technology, so much as Node the new shiny thing unburdened by browser differences.</p>

<p>I&#8217;ve actually visited Node a couple of times previously &#8211; if you haven&#8217;t at least installed it, you might be living under a rock &#8211; and I was flattered that <a href="http://dev.garann.com">Garann</a> asked me to review her book <a href="http://shop.oreilly.com/product/0636920023258.do">Node for Front-End Developers</a>, but past experiences had left me frustrated.</p>

<p>This time, something was different. I don&#8217;t rule out that it might be me, or even that learning some of the ins and outs of Ruby might have prepared me to understand Node &#8211; and packages and dependency management and writing for the server instead of the browser &#8211; better this time around. It could also be that the Node ecosystem has reached a point of maturity that it just hadn&#8217;t reached the last time I poked around.</p>

<p>Regardless, I found that everything made a whole lot more sense this time, and my struggles this time were about forgetting to stringify an object before sending it as a response to a request, not about getting the server to start in the first place. I used the <code>q</code> module to give me my beloved promises for managing all the asynchronicity, and generally found it ridiculously pleasant to leave behind all the context switching I&#8217;d grown accustomed to while using JavaScript and Ruby side by side. I&#8217;ll probably still turn to Ruby for automating things on the command line (though I continue to be intrigued by <a href="https://github.com/cowboy/grunt">grunt</a>), but I&#8217;m ready to admit that it&#8217;s time for me to add Node to my toolbox.</p>

<h2>Mocha</h2>

<p>To be honest, I&#8217;d just planned on using <a href="https://github.com/pivotal/jasmine">Jasmine</a> for writing tests for this project, mostly because I&#8217;d never set up Jasmine myself, and I was interested in maybe getting it working with grunt for headless testing. I ended up bailing on that plan when, in the course of some Googling for answers about Jasmine, I came across <a href="http://visionmedia.github.com/mocha/">Mocha</a>.</p>

<p>Mocha is a super-flexible testing framework that runs on Node and in the browser. You can choose your assertion library &#8211; that is, you can choose to write your tests like <code>assert(1, 1).ok()</code> or <code>expect(1).to.be(1)</code> depending on your preference. I decided to use the latter style, with the help of <a href="https://github.com/LearnBoost/expect.js">expect.js</a>. You can also choose your reporting style, including the ability to generate docs from your tests.</p>

<p>I had to do a bit of finagling to get the browser-based tests working with my
RequireJS setup, and ultimately I ended up just using my app&#8217;s server, running
in dev mode, to serve the tests in the browser. I&#8217;m still working out how best
to run just one test at a time in the browser, but all in all, discovering Mocha has probably been the best part of working on this project.</p>

<h2>RequireJS</h2>

<p><a href="http://requirejs.org/">RequireJS</a> is another tool that I&#8217;ve dabbled with in the past, but for the last 18 months I&#8217;ve been spending most of my time with Dojo&#8217;s pre-AMD build system, so I had some catching up to do. I don&#8217;t have a ton to say about RequireJS except:</p>

<ul>
<li>It&#8217;s gotten even easier to use since I last visited it.</li>
<li>The docs are great and also gorgeous.</li>
<li>While I haven&#8217;t had to bother him lately, James Burke, the author and maintainer of RequireJS, is a kind and incredibly helpful soul.</li>
<li>The <a href="http://requirejs.org/docs/api.html#text"><code>text!</code></a> plugin makes working with client-side templates incredibly simple, without cluttering up your HTML with templates in script tags or hard-coding your templates into your JavaScript.</li>
<li>The <a href="https://github.com/tbranyen/use.js"><code>use!</code></a> plugin makes it painless to treat libraries that don&#8217;t include AMD support just like libraries that do. I hear it might become an official plugin soon; I hope it will.</li>
</ul>


<h2>Backbone</h2>

<p>This part was a tough choice, and I actually set out to use a different framework but ended up getting cold feet &#8211; even though this was just a personal project, it did need to reach some semblance of done-ness in some reasonable period of time. After a little bit of poking around at other options, I decided that, barring completely copping out and using Dojo, Backbone was going to be the best tool for this particular job on this particular schedule.</p>

<p>I&#8217;m pretty torn about this, because I decided to use a framework that I <em>know</em> has shortcomings and limited magic, and I <em>know</em> that other options would serve me better in the long term. But I also know that the long term doesn&#8217;t exactly matter for this particular project. The thing that swayed me, really, was that with Backbone, I didn&#8217;t feel like I needed to grasp a whole slew of concepts before I could write my first line of code.</p>

<p>I looked up plenty of things along the way, and rewrote my fair share of code when I discovered that I&#8217;d been Doing It Wrong, but I was able to maintain a constant forward momentum. With the other options I considered, I felt like I was going to have to climb a ladder of unknown height before making any forward progress.</p>

<p>I feel like I made the right choice for this project, but it&#8217;s a choice I&#8217;d spend a lot more time on for a &#8220;real&#8221; project, and I&#8217;d be much more inclined to invest the initial energy in getting up to speed if the payoff was clearer. This, though, is a choice that people seem to be consistently terrible at, and so I feel like I should beat myself up about it just a little. It&#8217;s all too common to dig a ginormous hole for ourselves by choosing the technology that lets us start writing code the soonest; on the flip side, it&#8217;s all too common to choose a technology that&#8217;s complete overkill for the task at hand.</p>

<h2>The End</h2>

<p>The master branch of the <a href="https://github.com/rmurphey/srchr-demo">repo for the project</a> should be mostly stable (if incomplete) if you want to check it out. I&#8217;m going to close comments on this post in the hopes that you&#8217;ll write your own post about what you&#8217;ve been learning instead :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[JavaScript: It's a language, not a religion]]></title>
    <link href="http://rmurphey.com/blog/2012/04/04/javascript-a-language-not-a-religion/"/>
    <updated>2012-04-04T11:18:00-04:00</updated>
    <id>http://rmurphey.com/blog/2012/04/04/javascript-a-language-not-a-religion</id>
    <content type="html"><![CDATA[<p>I have six things to say:</p>

<ol>
<li><p>I am in a committed relationship with my partner Melissa. We will celebrate
six years together on Sunday. We contribute frequently to political causes.</p></li>
<li><p>I was deeply saddened yesterday to learn that Brendan Eich contributed money
in support of a <a href="http://en.wikipedia.org/wiki/California_Proposition_8">political initiative</a> that
sought to <em>rescind the court-established right for same-sex couples to
marry</em> in the state of California. It has changed my view of him as a
person, despite the fact that we have had a positive and professional
relationship and he has been a great supporter of my JavaScript career. I
think he is on the wrong side of history, and I hope that courts will
continue to agree with me.</p></li>
<li><p>I had a frank, private, and face-to-face conversation with Brendan about the
issue during JSConf. I shared my disappointment, sadness, and disagreement.</p></li>
<li><p>I have been dismayed to see this incident interpreted as a statement about
the JavaScript community as a whole. This community is made up of so many
people who believe so many different things, and yesterday I was reminded
that they are all just people, and JavaScript is just a language, not a
religion.  I shudder to think of a world where there is a political litmus
test for entry into the community.  Indeed, I am extremely torn about
introducing personal politics into my professional life*, as I fear it will
encourage professional colleagues to opine about personal beliefs that are
frankly none of their business. One of the great joys of working with
computers is that they <a href="http://raganwald.posterous.com/a-womans-story">do not care who I am or what I believe</a>;
I realize that to ask the same of people is unreasonable, but inviting
politics into the workplace is a treacherously slippery slope. Unless my
personal belief system presents an <em>imminent danger</em> to my colleagues, I am
loath to welcome discussion of it by people who otherwise have no
substantial or personal relationship with me.</p></li>
<li><p>I believe individual companies must determine how best to address these
issues, as their attitude toward them can have a significant impact on their
ability to hire and retain talented people. I support <em>constructive
pressure</em> on companies to align themselves with or distance themselves from
political causes, but I would not support a company that prohibited its
employees from participating in the political process. I urge anyone who is
hurt or offended by this incident to engage with Brendan and Mozilla
personally and professionally. Brendan is wrong on this issue, but he is a
thoughtful and intelligent person, and he is also a human being.</p></li>
<li><p>Finally: If this incident has made you angry or sad or disappointed, the most effective
thing you can do is follow in Brendan&#8217;s footsteps by <strong>putting your money
where your mouth is</strong>. Money speaks volumes in the American political
system, and there are campaigns in progress right now that will <a href="http://www.protectncfamilies.org/">impact the rights of gays and lesbians</a>.
Your <a href="https://protectallncfamilies.ngpvanhost.com/crmapi/contribute">contribution</a>
of $50, $100, or $1,000 &#8211; or, in lieu of money, your time &#8211; will have far
more impact than yet another angry tweet.</p></li>
</ol>


<p>And now I shall turn off the internet for a bit. Comments are disabled.
Shocker, I know.</p>

<p>* <em>It bears mentioning that, in certain cases, people making political
contributions are required to include information about their employer. The
inclusion of this information does not indicate that the employer supports &#8211;
or is even aware of &#8211; the contribution.</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bocoup]]></title>
    <link href="http://rmurphey.com/blog/2012/03/26/bocoup/"/>
    <updated>2012-03-26T10:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2012/03/26/bocoup</id>
    <content type="html"><![CDATA[<p><img src="http://rmurphey.com/images/bocoup.png" alt="bocoup" /></p>

<p>It wasn&#8217;t so long ago that I was giving my first talk about JavaScript at the
2009 jQuery Conference, and it was there that Bocoup&#8217;s Boaz Sender and Rick
Waldron created the (now-defunct) objectlateral.com, a celebration of an
unfortunate typo in the conference program&#8217;s listing of my talk.</p>

<p>A bond was forged, and ever since I&#8217;ve watched as <a href="http://bocoup.com">Bocoup</a>
has grown and prospered. I&#8217;ve watched them do mind-boggling work for the likes
of Mozilla, The Guardian, Google, and others, all while staying true to their
mission of embracing, contributing to, and evangelizing open-web technologies.</p>

<p>Today, I&#8217;m beyond excited &#8211; and also a wee bit humbled &#8211; to announce that
<a href="http://weblog.bocoup.com/welcome-rebecca-murphey">I&#8217;m joining their consulting team</a>.
As part of that role, I look forward to spending even more time working on and
talking about patterns and best practices for developing client-side JavaScript
applications. I also hope to work on new <a href="http://training.bocoup.com/">training offerings</a>
aimed at helping people make great client-side applications with web technology.</p>

<p>New beginnings have a terrible tendency to be accompanied by endings, and while
the Bocoup opportunity is one I couldn&#8217;t refuse, it&#8217;s with a heavy heart that I
bid farewell to the team at Toura. I&#8217;m proud of what we&#8217;ve built together, and
that we&#8217;ve shared so much of it with the developer community in the form of
<a href="http://github.com/Toura/mulberry">Mulberry</a>. The beauty of open source means
that I fully expect to continue working on and with Mulberry once I leave
Toura, but I know it won&#8217;t be the same.</p>

<p>I&#8217;ll be spending the next few days tying up loose ends at Toura, and then I&#8217;m
taking a break in April to hit JSConf, spend some time in Berlin, and head to
Warsaw to speak at <a href="http://2012.front-trends.com/">FrontTrends</a>. I&#8217;ll make my
way back home in time to start with Bocoup on May 1.</p>

<p>And so. To my teammates at Toura: I wish you nothing but the best, and look
forward to hearing news of your continued success. To Bocoup: Thanks for
welcoming me to the family. It&#8217;s been a long time coming, and I&#8217;m glad the day
is finally here.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Girls and Computers]]></title>
    <link href="http://rmurphey.com/blog/2012/03/25/girls-and-computers/"/>
    <updated>2012-03-25T12:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2012/03/25/girls-and-computers</id>
    <content type="html"><![CDATA[<p>After a week that seemed just chock full of
<a href="http://storify.com/ireneros/sexist-language-earns-sqoot-lots-of-fury">people</a>
being <a href="http://storify.com/charlesarthur/oh-hai-sexism">stupid</a> about women in
technology, I just found myself thinking back on how it was that I ended up
doing this whole computer thing in the first place.  I recorded a video a while
back for the <a href="http://highvisibilityproject.org/2011/10/rebecca-murphey/">High Visibility Project</a>, but that
really just told the story of how I ended up doing web development. The story
of how I got into computers begain when I was unequivocally a girl. It was
1982.</p>

<p>Back then, my dad made eyeglasses. My mom stayed at home with me and my
year-old sister &#8211; which she&#8217;d continue to do til I was a teenager, when my
brother finally entered kindergarten eight years later. Their mortgage was $79
&#8211; about $190 in today&#8217;s dollars &#8211; which is a good thing because my dad made
about $13,000 a year. We lived in Weedsport, New York, a small town just
outside of Syracuse. We walked to the post office to get our mail. The farmers
who lived just outside town were the rich people. In the winters the fire
department filled a small depression behind the elementary school with water
for a tiny skating rink. There were dish-to-pass suppers in the gym at church.</p>

<p>In 1982, Timex came out with the <a href="http://en.wikipedia.org/wiki/Timex_Sinclair">Timex Sinclair TS-1000</a>,
selling 500,000 of them in just six months. The computer, a few times thicker
than the original iPad but with about the same footprint, cost $99.95 &#8211; more
than that mortgage payment. When everyone else in town was getting cable,
my parents decided that three channels were good enough for them &#8211; it&#8217;s
possible they still had a black-and-white TV &#8211; and bought a computer instead.</p>

<p><img src="http://rmurphey.com/images/ts1000.JPG" alt="Timex Sinclair TS-1000" /></p>

<p>I remember tiny snippets of that time &#8211; playing kickball in my best friend
Beth&#8217;s yard, getting in trouble for tricking my mother into giving us milk that
we used to make mud pies, throwing sand in the face of my friend Nathan
because I didn&#8217;t yet appreciate that it really sucks to get sand thrown in your
face &#8211; but I vividly remember sitting in the living room of our house on
Horton Street with my father, playing with the computer.</p>

<p>A cassette player was our disk drive, and we had to set the volume just right
in order to read anything off a tape &#8211; there was actually some semblance of a
flight simulator program that we&#8217;d play, after listening to the tape player
screech for minutes on end. Eventually we upgraded the computer with a
fist-sized brick of RAM that we plugged into the back of the computer, bumping
our total capacity from 2K to 34K. I wrote programs in BASIC, though for the
life of me I can&#8217;t remember what any of them did. The programs that were the
most fun, though, were the ones whose assembly I painstakingly transcribed,
with my five-year-old fingers, from the back of magazines &#8211; pages and pages of
letters and numbers I didn&#8217;t understand on any level, and yet they made magic
happen if I got every single one right.</p>

<p>A string of computers followed. My parents bought a <a href="http://en.wikipedia.org/wiki/Coleco_Adam">Coleco Adam</a> when we moved
to Horseheads, New York &#8211; apparently the computer came with a certificate
redeemable for $500 upon my graduation from high school, but Coleco folded long
before they could cash it in. I made my first real money by typing a crazy
lady&#8217;s crazy manuscript about crazy food into an Apple IIe that we had plugged
into our TV, and my uncle and I spent almost the entirety of his visit from
Oklahoma writing a game of Yahtzee! on that computer, again in BASIC.</p>

<p><img src="http://rmurphey.com/images/rebecca-computer.jpg" alt="Me at a computer fair at the mall with my sister, my mother, and my friend
Michael" /></p>

<p><em>Above: Me at a computer fair at the mall with my sister, my
mother, and my friend Michael. &#8220;You were giving us all a tutorial, I can tell,&#8221;
says my mom. Note the 5-1/4&#8221; external floppy drive.</em></p>

<p>In middle school, I started a school newspaper, and I think we used some
prehistoric version of PageMaker to lay it out. When high school rolled around,
I toiled through hand-crafting the perfect letters and lines and arrows in
Technical Drawing so I could take CAD and CAM classes and make the computer
draw letters and lines and arrows for me, and quickly proceeded to school just
about every boy in the class. In my senior year of high school, I oversaw the
school yearbook&#8217;s transition from laying out pages on paper to laying out pages
with computers, this time the vaguely portable (it had a handle on the back!)
<a href="http://en.wikipedia.org/wiki/Macintosh_Classic">Mac Classic</a>.
We used PageMaker again; the screen was black and white and 9&#8221;, diagonally.</p>

<p><img src="http://rmurphey.com/images/mac-classic.jpg" alt="Macintosh Classic" /></p>

<p>It was around then that a friend gave me a modem and &#8211; to his eventual
chagrin, when he got the bill &#8211; access to his Delphi account, giving me my
first taste of the whole Internet thing in the form of telnet, gopher, and IRC.
When I went to college the following year, I took with me a computer with
perhaps a 10MB hard drive, and no mouse.</p>

<p>Once again I found myself poring over magazines to discover URIs and,
eventually, URLs that I could type to discover a whole new world of
information. In 1995, I spent the summer making my college newspaper&#8217;s web
site, previewing it in Lynx &#8211; it felt like there wasn&#8217;t much to learn when
there was so little difference between the markup and what I saw on the screen.
I would go to the computer lab to use NCSA&#8217;s Mosaic on the powerful RISC 6000
workstations, because they had a mouse. Yahoo! was about one year old. My
friend Dave, who lived down the street, installed Windows 95 that summer and
invited me over to show me. It was amazing. We were living in the future.</p>

<p>My early years with computers seem pretty tame &#8211; I wasn&#8217;t tearing them apart
or building my own or doing anything particularly interesting with them, but I
was using them, I was telling them what to do and they were mostly listening,
and <em>it never made me feel like I was weird</em>. To the contrary, it made me
feel powerful and empowered. I felt like a part of this ever-growing community
of people who understood, eventually, that computers were going to change the
world. It was the people who didn&#8217;t understand this who were weird and beneath
us. It was the people who understood computers better than me of whom I stood in
awe.</p>

<p>I can barely remember a time when computers weren&#8217;t a part of my life, and yet
when they first entered my life, their presence was incredibly exceptional.
These days, of course, computers are ubiquitous, but interaction with them at
the copy-assembly-from-the-back-of-a-magazine level is almost nonexistent.
Parents who can approach a computer with the same awe and wonder and
determination as a child &#8211; as I must imagine that my dad did in 1982 &#8211; are
likely equally rare.</p>

<p>In some ways, it is like the very ubiquity of technology has led us back to a
world where socially normative gender roles take hold all over again, and the
effort we&#8217;re going to need to put into overcoming that feels overwhelming
sometimes. Words can&#8217;t express my gratitude for the parents I have, for
that $99.95 investment they made in me, and for fact that I was lucky enough to
be 5 and full of wonder in 1982.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Thoughts on a (very) small project with Backbone and Backbone Boilerplate]]></title>
    <link href="http://rmurphey.com/blog/2012/03/11/thoughts-on-a-very-small-project-with-backbone-and-backbone-boilerplate/"/>
    <updated>2012-03-11T21:30:00-04:00</updated>
    <id>http://rmurphey.com/blog/2012/03/11/thoughts-on-a-very-small-project-with-backbone-and-backbone-boilerplate</id>
    <content type="html"><![CDATA[<p>I worked with <a href="http://documentcloud.github.com/backbone/">Backbone</a> and the
<a href="https://github.com/tbranyen/backbone-boilerplate">Backbone Boilerplate</a> for
the first time last weekend, putting together a small <a href="https://github.com/rmurphey/bvjs">demo app</a> for a presentation I gave last week at
BazaarVoice. I realize I&#8217;m about 18 months late to the Backbone party, here,
but I wanted to write down my thoughts, mostly because I&#8217;m pretty sure they&#8217;ll
change as I get a chance to work with both tools more.</p>

<h2>Backbone</h2>

<p>Backbone describes itself as a tool that &#8220;gives structure to web applications,&#8221;
but, at the risk of sounding pedantic, I think it would be more accurate to say
that it gives you tools that can help you structure your applications. There&#8217;s
incredibly little prescription about how to use the tools that Backbone
provides, and I have a feeling that the code I wrote to build my simple app
looks a lot different than what someone else might come up with.</p>

<p>This lack of prescription feels good and bad &#8211; good, because I was able to use
Backbone to pretty quickly set up an infrastructure that mirrored ones I&#8217;ve
built in the past; bad, because it leaves open the possibility of lots of
people inventing lots of wheels. To its credit, it packs a lot of power in a
very small package &#8211; 5.3k in production &#8211; but a real app is going to require
layering a lot more functionality on top of it. Ultimately, the best way to
think of Backbone is as the client-side app boilerplate you&#8217;d otherwise have to
write yourself.</p>

<p>My biggest complaint about Backbone is probably how unopinionated it is about
the view layer. Its focus seems to be entirely on the data layer, but the view
is still where we spend the vast majority of our time. Specifically, I think
Backbone could take a page from Dojo, and embrace the concept of &#8220;templated
widgets&#8221;, because that&#8217;s what people seem to be doing with Backbone views
anyway: mixing data with a template to create a DOM fragment, placing that
fragment on the page, listening for user interaction with the fragment, and
updating it as required. Backbone provides for some of this, specifically the
event stuff, but it leaves you to write your own functionality when it comes to
templating, placing, and updating. I think this is a solveable problem without
a whole lot of code, and want to spend some time trying to prove it, but I know
I need to look into the Backbone Layout Manager before I get too carried away.</p>

<h2>Backbone Boilerplate</h2>

<p>This project from Tim Branyen was a life-saver &#8211; it gave me an absolutely
enormous head start when it came to incorporating
<a href="http://requirejs.org/">RequireJS</a>, setting up my application directories, and
setting up a development server. It also included some great inline docs that
helped me get my bearings with Backbone.</p>

<p>There are a couple of ways I think the boilerplate could be improved, and I&#8217;d be
curious for others&#8217; opinions:</p>

<ul>
<li>The sample app includes the concept of &#8220;modules,&#8221; which seem to be a single
file that include the models, collections, views, and routes for a &#8230;
module. I don&#8217;t love the idea of combining all of this into a single file,
because it seems to discourage smart reuse and unit testing of each piece of
functionality. In the app I created, I abandoned the concept of modules, and
instead broke my app into &#8220;components&#8221;, &#8220;controllers&#8221;, and &#8220;services&#8221;. I
explain this breakdown in a bit more depth in the <a href="http://www.slideshare.net/rmurphey/bvjs">presentation I gave at BazaarVoice</a>. I&#8217;m not sure this is
the right answer for all apps, but I think modules oversimplify things.</li>
<li>The boilerplate includes a <code>namespace.js</code> file. It defines a namespace
object, and that object includes a <code>fetchTemplate</code> method. It seems this
method should only be used by views, and so I&#8217;d rather see something along
the lines of an enhanced View that provides this functionality. That&#8217;s what I
did with the <a href="https://github.com/rmurphey/bvjs/blob/master/app/components/base.js">base component module</a>
in my sample app.</li>
<li>I&#8217;m super-glad to see Jasmine included in the test directory, but
unfortunately the examples show how to write Jasmine tests, not Jasmine tests
for a Backbone app. As a community, we definitely need to be showing more
examples of how to test things, and this seems like a good opportunity to
distribute that knowledge.</li>
</ul>


<h2>Overall</h2>

<p>I feel a little silly that I&#8217;m just now getting around to spending any time
with Backbone, and I know that I only scratched the surface, but I like what I
saw. I think it&#8217;s important to take it for what it is: an uber-tiny library
that gets you pointed in the right direction. What I really want to see are
fuller-fledged frameworks that build on top of Backbone, because I think
there&#8217;s a lot more that can be standardized beyond what Backbone offers. I&#8217;m
hoping to have a bit more time in April to dig in, and hopefully I can flesh
out some of these ideas into something useful.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Community Conferences]]></title>
    <link href="http://rmurphey.com/blog/2012/03/08/community-conferences/"/>
    <updated>2012-03-08T08:29:00-05:00</updated>
    <id>http://rmurphey.com/blog/2012/03/08/community-conferences</id>
    <content type="html"><![CDATA[<p>In 2010, I helped put on the first TXJS. We sold our first tickets for $29, and
I think the most expensive tickets went for something like $129. We had about
200 people buy tickets, we had speakers like Douglas Crockford, Paul Irish, and
John Resig, and we had sponsors like Facebook and Google. Our total budget was
something like $30,000, and every out-of-town speaker had their travel and
accommodations paid for.</p>

<p>In May, O&#8217;Reilly Media is holding another JavaScript conference in San
Francisco, called FluentConf. I recently came to know that they are charging
$100,000 for top-tier sponsorships, and that they are offering a 10-minute
keynote as part of the package.</p>

<p>This turned my stomach, and not just because I believe it cheapens the
experience of attendees, who will pay hundreds of dollars themselves. What
really upset me was that a few weeks ago, I was approached to be on the speaker
selection committee of FluentConf, and that conversation led me to discover
that FluentConf would not be paying for speaker travel and accommodations. And
so the other day, I tweeted:</p>

<blockquote><p>conference #protip: save your money &#8211; and your speaking skills &#8211; for events that don&#8217;t sell their keynotes for $100k</p></blockquote>

<p>Last night, I was at the Ginger Man in Austin, and I checked the Twitters,
discovering that Peter Cooper, one of the chairs of FluentConf, had replied to
a conversation that arose from that tweet:</p>

<blockquote><p>@rmurphey @tomdale If you&#8217;re referring to Fluent, that is news to me.</p></blockquote>

<p>I will accept the weird fact that the co-chair of a conference didn&#8217;t know its
speaking slots were for sale &#8211; I gather that it is essentially a volunteer
role, and the co-chairs aren&#8217;t necessarily in the driver&#8217;s seat when it comes
to decisions like this. I let Peter know that, indeed, I had a PDF that
outlined all the sponsorship options.</p>

<p>This is the part where, in some alternate reality, a mutual understanding of
the offensiveness of this fact would have been achieved. What happened instead
was a whole lot of name-calling, misquoting, and general weirdness.</p>

<p>Here&#8217;s the deal. Conferences can run their event however they want, and they
can make money hand over fist. They can even claim they are the giving
JavaScript developers &#8220;an event of their own,&#8221; ignoring the existence of
the actual community-run JavaScript events that have been around for years now.  I
probably won&#8217;t go to or speak at an event that makes money hand over fist, but
I don&#8217;t have any problem with the existence of such events, or with people&#8217;s
involvement with them.  However, when a conference is making money hand over
fist &#8211; my back of the napkin calculations would suggest that FluentConf stands
to have revenues of well over a million dollars &#8211; then that conference has no
excuse not to pay the relatively paltry costs associated with speaker travel
and accommodations.</p>

<p>A conference does not exist without its speakers. Those who speak at an event
&#8211; the good ones, anyway &#8211; spend countless hours preparing and rehearsing, and
they are away from home and work for days. While I do not discount the benefits
that accrue to good speakers, the costs of being a speaker are non-trivial &#8211;
and that&#8217;s <em>before</em> you get into the dollar costs of travel and accommodations.</p>

<p>When an event is unwilling to cover even those hard costs &#8211; nevermind the
preparation time and time away from work and home &#8211; it materially affects the
selection of speakers.  It&#8217;s even worse when those same conferences claim to
desire <a href="http://fluentconf.com/fluent2012/public/content/about#diversity">diversity</a>;
the people they claim to want so badly are the very people most likely to be
discouraged when they find out they have to pay their own way to the stage.</p>

<p>In the conversation last night, I made this point:</p>

<blockquote><p>when only the people who can afford to speak can speak, then only the people who can afford to speak will
speak.</p></blockquote>

<p>Amy Hoy responded with a criticism of community-run conferences:</p>

<blockquote><p>and when only ppl who can order a ticket in 3 seconds can afford to come, only ppl who can order a ticket in 3 seconds can come</p></blockquote>

<p>I know that getting tickets to the actual community-run events is hard, but
that is because the community-run events flat-out ignore the economics of
supply and demand, choosing instead to sell tickets at affordable prices even
if it means they will sell out in a heartbeat, leaving a boatload of potential
profit on the table. And yet those events &#8211; JSConf, TXJS, and the like &#8211; have
still figured out how to cover speaker costs and provide attendees and sponsors
with unforgettable experiences.</p>

<p>When an event with revenues exceeding a million dollars is unwilling to cover
those costs, while simultaneously selling speaking slots, I do not hesitate for
a moment to call that event out, and I do not hesitate to call
on <a href="http://fluentconf.com/fluent2012/public/content/about#commitee">respected members of the community</a> to sever
their ties with the event. I&#8217;m not embarrassed about it, and you can call me all
the names you want.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mulberry: A development framework for mobile apps]]></title>
    <link href="http://rmurphey.com/blog/2011/09/18/introducing-mulberry/"/>
    <updated>2011-09-18T11:30:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/09/18/introducing-mulberry</id>
    <content type="html"><![CDATA[<p>I&#8217;ll be getting on stage in a bit at <a href="http://capitoljs.com">CapitolJS</a>, another
great event from Chris Williams, the creator of JSConf and all-around
conference organizer extraordinaire. My schtick at conferences in the past has
been to talk about the pain and pitfalls of large app development with
JavaScript, but this time is a little different: I&#8217;ll be announcing that <a href="http://toura.com">Toura Mobile</a> has created a framework built on top of PhoneGap that
aims eliminate some of those pains and pitfalls for mobile developers. We&#8217;re
calling it <a href="http://mulberry.toura.com">Mulberry</a>, and you&#8217;ll be seeing it on GitHub in the next few weeks.</p>

<p><strong>tl;dr</strong>: <a href="http://mulberry.toura.com">go here</a> and <a href="http://mulberry.toura.com/#tour">watch this video</a>.</p>

<p>While the lawyers are dotting the i&#8217;s and crossing the t&#8217;s as far as getting the code in your hands &#8211; we&#8217;re aiming for a permissive license similar to the licenses for PhoneGap and Dojo &#8211; I wanted to tell you a little bit about it.</p>

<p>Mulberry is two things. First, it&#8217;s command line tools (written in Ruby) that help you rapidly scaffold and configure an app, create content using simple Markdown and YAML, and test it in your browser, in a simulator, and on device. Second, and much more exciting to me as a JavaScript developer, it&#8217;s a framework built on top of the Dojo Toolkit for structuring an application and adding custom functionality in a sane way.</p>

<p>Mulberry lets you focus on the things that are unique to your application. It provides an underlying framework that includes a &#8220;router&#8221; for managing application state; built-in components and templates for displaying standard content types like text, audios, videos, feeds, and images; a simple API for defining custom functionality and integrating it with the system; and an HTML/CSS framework that uses SASS and HAML templates to make it easy to style your apps.</p>

<p>The basics of setting up an app are pretty well covered at the <a href="http://mulberry.toura.com">Mulberry
site</a>, but if you&#8217;re reading this, you&#8217;re probably a JavaScript developer, so I want to focus here on what Mulberry can do for you. First, though, let me back up and cover some terminology: Mulberry apps consist of a set of &#8220;nodes&#8221;; each node is assigned a template, and each template consists of components arranged in a layout. Nodes can have assets associated with them &#8211; text, audio, images, video, feeds, and data.</p>

<p>It&#8217;s the data asset that provides the most power to developers &#8211; you can create an arbitrary object, associate it with a node, and then any components that are in the template that&#8217;s being used to display the node will get access to that data.</p>

<p>A Twitter component offers a simple example. A node might have a data asset like this associated with it:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="p">{</span> <span class="nx">term</span> <span class="o">:</span> <span class="s1">&#39;capitoljs&#39;</span><span class="p">,</span> <span class="nx">type</span> <span class="o">:</span> <span class="s1">&#39;twitter&#39;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>We could define a custom template for this page (<code>mulberry create_template Twitter</code>), and tell that template to include a Twitter component:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='yaml'><span class='line'><span class="l-Scalar-Plain">Twitter</span><span class="p-Indicator">:</span>
</span><span class='line'>  <span class="l-Scalar-Plain">screens</span><span class="p-Indicator">:</span>
</span><span class='line'>    <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">index</span>
</span><span class='line'>      <span class="l-Scalar-Plain">regions</span><span class="p-Indicator">:</span>
</span><span class='line'>        <span class="p-Indicator">-</span>
</span><span class='line'>          <span class="l-Scalar-Plain">size</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">fixed</span>
</span><span class='line'>          <span class="l-Scalar-Plain">scrollable</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">false</span>
</span><span class='line'>          <span class="l-Scalar-Plain">components</span><span class="p-Indicator">:</span>
</span><span class='line'>            <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">PageNav</span>
</span><span class='line'>        <span class="p-Indicator">-</span>
</span><span class='line'>          <span class="l-Scalar-Plain">size</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">flex</span>
</span><span class='line'>          <span class="l-Scalar-Plain">scrollable</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">true</span>
</span><span class='line'>          <span class="l-Scalar-Plain">components</span><span class="p-Indicator">:</span>
</span><span class='line'>            <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">PageHeaderImage</span>
</span><span class='line'>            <span class="p-Indicator">-</span> <span class="l-Scalar-Plain">custom:Twitter</span>
</span></code></pre></td></tr></table></div></figure>


<p>Next, we&#8217;d define our Twitter component (<code>mulberry create_component Twitter</code>), which would create the skeleton of a component file:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">dojo</span><span class="p">.</span><span class="nx">provide</span><span class="p">(</span><span class="s1">&#39;client.components.Twitter&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">toura</span><span class="p">.</span><span class="nx">component</span><span class="p">(</span><span class="s1">&#39;Twitter&#39;</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">componentTemplate</span> <span class="o">:</span> <span class="nx">dojo</span><span class="p">.</span><span class="nx">cache</span><span class="p">(</span><span class="s1">&#39;client.components&#39;</span><span class="p">,</span> <span class="s1">&#39;Twitter/Twitter.haml&#39;</span><span class="p">),</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">prep</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">init</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>One of the things the skeleton contains is a reference to the template for the component. The <code>create_component</code> command creates this file, which defines the DOM structure for the component. For the sake of this component, that template will just need to contain one line:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='haml'><span class='line'><span class="nt">%ul</span><span class="nc">.component.twitter</span>
</span></code></pre></td></tr></table></div></figure>


<p>As I mentioned earlier, Mulberry components automatically get access to all of the assets that are attached to the node they&#8217;re displaying. This information is available as an object at <code>this.node</code>. Mulberry components also have two default methods that you can implement: the <code>prep</code> method and the <code>init</code> method.</p>

<p>The <code>prep</code> method is an opportunity to prepare your data before it&#8217;s rendered using the template; we won&#8217;t use it for the Twitter component, because the Twitter component will go out and fetch its data <em>after</em> the template is rendered. This is where the <code>init</code> method comes in &#8211; this is where you can tell your component what to do. Here&#8217;s what our Twitter component ends up looking like:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">dojo</span><span class="p">.</span><span class="nx">provide</span><span class="p">(</span><span class="s1">&#39;client.components.Twitter&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="nx">mulberry</span><span class="p">.</span><span class="nx">component</span><span class="p">(</span><span class="s1">&#39;Twitter&#39;</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">componentTemplate</span> <span class="o">:</span> <span class="nx">dojo</span><span class="p">.</span><span class="nx">cache</span><span class="p">(</span><span class="s1">&#39;client.components&#39;</span><span class="p">,</span> <span class="s1">&#39;Twitter/Twitter.haml&#39;</span><span class="p">),</span>
</span><span class='line'>  <span class="nx">tweetTemplate</span> <span class="o">:</span> <span class="nx">dojo</span><span class="p">.</span><span class="nx">cache</span><span class="p">(</span><span class="s1">&#39;client.components&#39;</span><span class="p">,</span> <span class="s1">&#39;Twitter/Tweet.haml&#39;</span><span class="p">),</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">init</span> <span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">dojo</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">node</span><span class="p">.</span><span class="nx">data</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="k">return</span> <span class="nx">d</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;twitter&#39;</span>
</span><span class='line'>        <span class="p">})[</span><span class="mi">0</span><span class="p">].</span><span class="nx">json</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">(</span><span class="s1">&#39;http://search.twitter.com/search.json?q=&#39;</span> <span class="o">+</span> <span class="nx">data</span><span class="p">.</span><span class="nx">term</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">dataType</span> <span class="o">:</span> <span class="s1">&#39;jsonp&#39;</span><span class="p">,</span>
</span><span class='line'>      <span class="nx">success</span> <span class="o">:</span> <span class="nx">$</span><span class="p">.</span><span class="nx">proxy</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s1">&#39;_onLoad&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">_onLoad</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">tweets</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">results</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">tpl</span> <span class="o">=</span> <span class="nx">mulberry</span><span class="p">.</span><span class="nx">haml</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">tweetTemplate</span><span class="p">),</span>
</span><span class='line'>        <span class="nx">html</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">tweets</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tweet</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>          <span class="nx">tweet</span><span class="p">.</span><span class="nx">link</span> <span class="o">=</span> <span class="s1">&#39;http://twitter.com/capitoljs/status/&#39;</span> <span class="o">+</span> <span class="nx">tweet</span><span class="p">.</span><span class="nx">id_str</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>          <span class="nx">tweet</span><span class="p">.</span><span class="nx">created_at</span> <span class="o">=</span> <span class="nx">dojo</span><span class="p">.</span><span class="nx">date</span><span class="p">.</span><span class="nx">locale</span><span class="p">.</span><span class="nx">format</span><span class="p">(</span>
</span><span class='line'>            <span class="k">new</span> <span class="nb">Date</span><span class="p">(</span><span class="nx">tweet</span><span class="p">.</span><span class="nx">created_at</span><span class="p">),</span> <span class="p">{</span>
</span><span class='line'>              <span class="nx">datePattern</span> <span class="o">:</span> <span class="s1">&#39;EEE&#39;</span><span class="p">,</span>
</span><span class='line'>              <span class="nx">timePattern</span> <span class="o">:</span> <span class="s1">&#39;h:m a&#39;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>          <span class="p">);</span>
</span><span class='line'>
</span><span class='line'>          <span class="nx">tweet</span><span class="p">.</span><span class="nx">text</span> <span class="o">=</span> <span class="nx">tweet</span><span class="p">.</span><span class="nx">text</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span>
</span><span class='line'>            <span class="sr">/@(\S+)/g</span><span class="p">,</span>
</span><span class='line'>            <span class="s2">&quot;&lt;a href=&#39;http://twitter.com/#!/$1&#39;&gt;@$1&lt;/a&gt;&quot;</span>
</span><span class='line'>          <span class="p">);</span>
</span><span class='line'>
</span><span class='line'>          <span class="k">return</span> <span class="nx">tpl</span><span class="p">(</span><span class="nx">tweet</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}).</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39;&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">$domNode</span><span class="p">.</span><span class="nx">html</span><span class="p">(</span><span class="nx">html</span><span class="p">);</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">region</span><span class="p">.</span><span class="nx">refreshScroller</span><span class="p">();</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note that when we define the <code>data</code> variable in the init method, we look at <code>this.node.data</code>, which is an array of all of the data objects associated with the node. We filter this array to find the first data object that is the right type &#8211; this means we can have lots of different data objects associated with a given node.</p>

<p>Note also that there&#8217;s a property <code>this.$domNode</code> that we&#8217;re calling jQuery methods on, and that we&#8217;re using jQuery&#8217;s <code>$.ajax</code> &#8211; Mulberry apps come with jQuery enabled by default, and if it&#8217;s enabled, helpers like <code>this.$domNode</code> become available to you. This means that very little knowledge of Dojo is required to start adding your own functionality to an app &#8211; if you need it, though, the full power of the Dojo Toolkit is available to you too.</p>

<p>Here&#8217;s what our component ends up looking like, with a little bit of custom CSS applied to our app:</p>

<p><img src="http://www.rebeccamurphey.com/i/4e760b2ff3b5b.jpg" title="A Mulberry app using a custom Twitter component" alt="screenshot" /></p>

<p>This is a pretty basic demo &#8211; Twitter is, indeed, the new <code>hello world</code> &#8211; but I hope it gives you a little bit of an idea about what you might be able to build with Mulberry. We&#8217;ve been using it in production to create content-rich mobile apps for our users for months now (connected to a web-based CMS instead of the filesystem, of course), and we&#8217;ve designed it specifically to be flexible enough to meet arbitrary client requests without the need to re-architect the underlying application.</p>

<p>If you know JavaScript, HTML, and CSS, Mulberry is a powerful tool to rapidly create a content-rich mobile application while taking advantage of an established infrastructure, rather than building it yourself. I&#8217;m excited to see what you&#8217;ll do with it!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Switching to Octopress]]></title>
    <link href="http://rmurphey.com/blog/2011/07/25/switching-to-octopress/"/>
    <updated>2011-07-25T08:14:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/07/25/switching-to-octopress</id>
    <content type="html"><![CDATA[<p>I&#8217;m taking a stab at starting a new blog at
<a href="http://rmurphey.com">rmurphey.com</a>, powered by
<a href="http://octopress.org/">Octopress</a>, which is a set of tools, themes, and other
goodness around a static site generator (SSG) called
<a href="https://github.com/mojombo/jekyll">jekyll</a>. A couple of people have noticed
the new site and wondered what I&#8217;m doing, so I thought I&#8217;d take a couple of
minutes to explain.</p>

<p>My old blog at <a href="http://blog.rebeccamurphey.com">blog.rebeccamurphey.com</a> is
managed using <a href="http://posterous.com">Posterous</a>. It used to be a self-hosted
WordPress site, but self-hosted WordPress sites are so 2009. One too many
attacks by hackers made it way more trouble than it seemed to be worth.
Posterous made switching from a WordPress install pretty easy, so, I did that.
All told, it took a few hours, and I was pretty happy.</p>

<p>For a few reasons, the old blog isn&#8217;t going anywhere:</p>

<ul>
<li>I ran into some trouble importing the old content into jekyll. I was tired
and I didn&#8217;t investigate the issues too much, so they&#8217;re probably solveable,
but &#8230;</li>
<li>Some of the old content just isn&#8217;t that good, and since time is a finite
resource, I don&#8217;t want to get too wrapped up in moving it over. Plus &#8230;</li>
<li>Frighteningly or otherwise, some of my posts have become reference material
on the internet. If I move them, I&#8217;ve got to deal with redirections, and I
have a feeling that&#8217;s not going to be an easy task with Posterous.</li>
</ul>


<p>In hindsight, I should have switched directly from WordPress to an SSG. Despite
my many complaints about Posterous &#8211; misformatted posts, lack of comment
hyperlinks, a sign-in requirement for commenting, and lots more &#8211; in the end
my decision to switch to a static site generator instead was more about having
easy control over my content <em>on my filesystem</em>.</p>

<p><a href="http://blog.guestlistapp.com/post/2304152860/five-reasons-to-use-a-static-site-generator-instead-of">This article</a>
explains it well, but the bottom line, I think, is that static site generators
are blogging tools for people who don&#8217;t need all the bullshit that&#8217;s been added
to online tools in the interest of making them usable by people who don&#8217;t know
wtf they&#8217;re doing. So, yes, to use an SSG, you have to know wtf you&#8217;re doing,
and for me that&#8217;s a good thing: the tool gets out of my way and lets me focus
on the writing.</p>

<p>As for Octopress, it seems pretty damn nifty &#8211; the default theme looks gorgeous on my
desktop and on my phone, and it seems they&#8217;ve taken care to put common
customization points in a single sass file. All that aside, though, one of my favorite parts
about it is that my content is truly my content. If Octopress pisses me off &#8211;
though I hope it won&#8217;t! &#8211; then I can simply take my markdown files and put
them in some other SSG, upload the whole thing to my GitHub pages, and be done
with it. Win all around.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using object literals for flow control and settings]]></title>
    <link href="http://rmurphey.com/blog/2011/07/24/object-literals/"/>
    <updated>2011-07-24T00:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/07/24/object-literals</id>
    <content type="html"><![CDATA[<p>I got an email the other day from someone reading through <a href="http://jqfundamentals.com">jQuery Fundamentals</a> &#8211; they&#8217;d come across the section
about patterns for performance and compression, which is based on a
presentation by <a href="http://paulirish.com">Paul Irish</a> gave back at the 2009 jQuery
Conference in Boston.</p>

<p>In that section, there&#8217;s a bit about alternative patterns for flow control &#8211;
that is, deciding what a program should do next. We&#8217;re all familiar with the
standard if statement:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">isAnimal</span><span class="p">(</span><span class="nx">thing</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">thing</span> <span class="o">===</span> <span class="s1">&#39;dog&#39;</span> <span class="o">||</span> <span class="nx">thing</span> <span class="o">===</span> <span class="s1">&#39;cat&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;yes!&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;no&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>What stumped the person who emailed me, though, was when the same logic as we
see above was written like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">isAnimal</span><span class="p">(</span><span class="nx">thing</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(({</span> <span class="nx">cat</span> <span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">dog</span> <span class="o">:</span> <span class="mi">1</span> <span class="p">})[</span> <span class="nx">thing</span> <span class="p">])</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;yes!&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;no&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>What&#8217;s happening here is that we&#8217;re using a throwaway object literal to express
the conditions under which we will say a <code>thing</code> is an animal. We could have
stored the object in a variable first:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">isAnimal</span><span class="p">(</span><span class="nx">thing</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">animals</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">cat</span> <span class="o">:</span> <span class="mi">1</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">dog</span> <span class="o">:</span> <span class="mi">1</span>
</span><span class='line'>  <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">animals</span><span class="p">[</span> <span class="nx">thing</span> <span class="p">])</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;yes!&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;no&quot;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>However, that variable&#8217;s only purpose would be to provide this one lookup, so
it can be argued that the version that doesn&#8217;t bother setting the variable is
more economical. Reasonable people can probably disagree about whether this
economy of bytes is a good tradeoff for readability &#8211; something like this is
perfectly readable to a seasoned developer, but potentially puzzling otherwise
&#8211; but it&#8217;s an interesting example of how we can use literals in JavaScript
without bothering to store a value in a variable.</p>

<p>The pattern works with an array, too:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">animalByIndex</span><span class="p">(</span><span class="nx">index</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">[</span> <span class="s1">&#39;cat&#39;</span><span class="p">,</span> <span class="s1">&#39;dog&#39;</span> <span class="p">][</span> <span class="nx">index</span> <span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>It&#8217;s also useful for looking up values generally, which is how I find myself
using it most often these days in my work with <a href="http://toura.com">Toura</a>, where
we routinely branch our code depending on the form factor of the device we&#8217;re
targeting:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">getBlingLevel</span><span class="p">(</span><span class="nx">device</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">return</span> <span class="p">({</span>
</span><span class='line'>    <span class="nx">phone</span> <span class="o">:</span> <span class="mi">100</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">tablet</span> <span class="o">:</span> <span class="mi">200</span>
</span><span class='line'>  <span class="p">})[</span> <span class="nx">device</span><span class="p">.</span><span class="nx">type</span> <span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>As an added benefit, constructs that use this pattern will return the
conveniently falsy <code>undefined</code> if you try to look up a value that doesn&#8217;t have
a corresponding property in the object literal.</p>

<p>A great way to come across techniques like this is to read the source code of
your favorite library (and other libraries too). Unfortunately, once
discovered, these patterns can be difficult to decipher, even if you have
pretty good Google fu. Just in case your neighborhood blogger isn&#8217;t available,
IRC is alive and well in 2011, and it&#8217;s an excellent place to get access to
smart folks eager to take the time to explain.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Lessons From a Rewrite]]></title>
    <link href="http://rmurphey.com/blog/2011/07/06/lessons-from-a-rewrite/"/>
    <updated>2011-07-06T10:50:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/07/06/lessons-from-a-rewrite</id>
    <content type="html"><![CDATA[<p>MVC and friends have been around for decades, but it’s only in the last couple
of years that broad swaths of developers have started applying those patterns
to JavaScript. As that awareness spreads, developers eager to use their
newfound insight are presented with a target-rich environment, and the
temptation to rewrite can be strong.</p>

<blockquote><p>There’s a subtle reason that programmers always want to throw away the code
and start over. The reason is that they think the old code is a mess. … The reason
that they think the old code is a mess is because of a cardinal, fundamental
law of programming: It’s harder to read code than to write it. - <a href="http://www.joelonsoftware.com/articles/fog0000000069.html"> Joel Spolsky
</a></p></blockquote>

<p>When I started working with <a href="http://toura.com/"> Toura Mobile </a> late last year, they already had
a product: a web-based CMS to create the structure of a mobile application and
populate it with content, and a PhoneGap-based application to consume the
output of the CMS inside a native application. Customers were paying, but the
development team was finding that delivering new features was a struggle, and
bug fixes seemed just as likely to break something else as not. They contacted
me to see whether they should consider a rewrite.</p>

<p>With due deference to Spolsky, I don’t think it was a lack of readability
driving their inclination to rewrite. In fact, the code wasn’t all that
difficult to read or follow. The problem was that the PhoneGap side of things
had been written to solve the problems of a single-purpose, one-off
application, and it was becoming clear that it needed to be a flexible,
extensible delivery system for all of the content combinations clients could
dream up. It wasn’t an app — it was an app that made there be an app.</p>

<blockquote><p>Where a new system concept or new technology is used, one has to build a system
to throw away, for even the best planning is not so omniscient as to get it
right the first time. Hence plan to throw one away; you will, anyhow. - Fred
Brooks, <a href="http://en.wikipedia.org/wiki/The_Mythical_Man-Month"> The Mythical Man Month </a></p></blockquote>

<p>By the time I’d reviewed the code and started writing up my findings, the
decision had already been made: Toura was going to throw one away and start
from scratch. For four grueling and exciting months, I helped them figure out
how to do it better the second time around. In the end, I like to think we’ve
come up with a solid architecture that’s going to adapt well to clients’
ever-changing needs. Here, then, are some of the lessons we learned along the
way.</p>

<h2>Understand what you’re rewriting</h2>

<p>I had spent only a few days with the codebase when we decided that we were
going to rewrite it. In some ways, this was good — I was a fresh set of eyes,
someone who could think about the system in a new way — but in other ways, it
was a major hindrance. We spent a lot of time at the beginning getting me up to
speed on what, exactly, we were making; things that went without saying for
existing team members did not, in fact, go without saying for me.</p>

<p>This constant need for explanation and clarification was frustrating at times,
both for me and for the existing team, but it forced us to state the problem in
plain terms. The value of this was incredible — as a team, we were far less
likely to accept assumptions from the original implementation, even assumptions
that seemed obvious.</p>

<p>One of the key features of Toura applications is the ability to update them
“over the air” — it’s not necessary to put a new version in an app store in
order to update an app’s content or even its structure. In the original app,
this was accomplished via generated SQL diffs of the data. If the app was at
version 3, and the data in the CMS was at version 10, then the app would
request a patch file to upgrade version 3 to version 10. The CMS had to
generate a diff for all possible combinations: version 3 to version 10, version
4 to version 10, etc. The diff consisted of queries to run against an SQLite
database on the device. Opportunities for failures or errors were rampant,
a situation exacerbated by the async nature of the SQLite interface.</p>

<p>In the new app, we replicated the feature with vastly less complexity
— whenever there is an update, we just make the full data available at an
app-specific URL as a JSON file, using the same format that we use to provide
the initial data for the app on the device. The new data is stored on the
device, but it’s also retained in memory while the application is running via
Dojo’s Item File Read Store, which allows us to query it synchronously. The
need for version-by-version diffs has been eliminated.</p>

<p>Restating the problem led to a simpler, more elegant solution that greatly
reduced the opportunities for errors and failure. As an added benefit, using
JSON has allowed us to meet needs that we never anticipated — the flexibility
it provides has become a valuable tool in our toolbox.</p>

<h2>Identify pain points</h2>

<p>If the point of a rewrite is to make development easier, then an important step
is to figure out what, exactly, is making development hard. Again, this was
a time to question assumptions — as it turned out, there were things that had
come to be accepted burdens that were actually relatively easy to address.</p>

<p>One of the biggest examples of this was the time required to develop and test
anything that might behave differently on one operating system versus another.
For example, the Android OS has limited support for the audio and video tags,
so a native workaround is required to play media on Android that is not
required on iOS.</p>

<p>In the original code, this device-specific branching was handled in a way that
undoubtedly made sense at the beginning but grew unwieldy over time. Developers
would create Mustache templates, wrapping the template tags in <code>/* */</code> so the
templates were actually executable, and then compile those templates into plain
JavaScript files for production. Here are a few lines from one of those
templates:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="cm">/*  */</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">mediaPath</span> <span class="o">=</span> <span class="s2">&quot;www/media/&quot;</span> <span class="o">+</span> <span class="nx">toura</span><span class="p">.</span><span class="nx">pages</span><span class="p">.</span><span class="nx">currentId</span> <span class="o">+</span> <span class="s2">&quot;/&quot;</span><span class="p">;</span>
</span><span class='line'><span class="cm">/*  */</span>
</span><span class='line'><span class="cm">/*  */</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">mediaPath</span> <span class="o">=</span> <span class="p">[</span><span class="nx">Toura</span><span class="p">.</span><span class="nx">getTouraPath</span><span class="p">(),</span> <span class="nx">toura</span><span class="p">.</span><span class="nx">pages</span><span class="p">.</span><span class="nx">currentId</span><span class="p">].</span><span class="nx">join</span><span class="p">(</span><span class="s2">&quot;/&quot;</span><span class="p">);</span>
</span><span class='line'><span class="cm">/*  */</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">imagesList</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">dimensionsList</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">namesList</span> <span class="o">=</span> <span class="p">[],</span> <span class="nx">thumbsList</span> <span class="o">=</span> <span class="p">[];</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">pos</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="nx">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="cm">/*  */</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">count</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'><span class="cm">/*  */</span>
</span></code></pre></td></tr></table></div></figure>


<p>These templates were impossible to check with a code quality tool like JSHint,
because it was standard to declare the same variable multiple times. Multiple
declarations of the same variable meant that the order of those declarations
was important, which made the templates tremendously fragile. The theoretical
payoff was smaller code in production, but the cost of that byte shaving was
high, and the benefit somewhat questionable — after all, we’d be delivering the
code directly from the device, not over HTTP.</p>

<p>In the rewrite, we used a simple configuration object to specify information
about the environment, and then we look at the values in that configuration
object to determine how the app should behave. The configuration object is
created as part of building a production-ready app, but in development we can
alter configuration settings at will. Simple <code>if</code> statements replaced fragile
template tags.</p>

<p>Since Dojo allows specifying code blocks for exclusion based on the settings
you provide to the build process, we could mark code for exclusion if we really
didn’t want it in production.</p>

<p>By using a configuration object instead of template tags for branching, we
eliminated a major pain point in day-to-day development. While nothing matches
the proving ground of the device itself, it’s now trivial to effectively
simulate different device experiences from the comfort of the browser. We do
the majority of our development there, with a high degree of confidence that
things will work mostly as expected once we reach the device. If you’ve ever
waited for an app to build and install to a device, then you know how much
faster it is to just press Command-R in your browser instead.</p>

<h2>Have a communication manifesto</h2>

<p>Deciding that you’re going to embrace an MVC-ish approach to an application is
a big step, but only a first step — there are a million more decisions you’re
going to need to make, big and small. One of the widest-reaching decisions to
make is how you’ll communicate among the various pieces of the application.
There are all sorts of levels of communication, from application-wide state
management — what page am I on? — to communication between UI components — when
a user enters a search term, how do I get and display the results?</p>

<p>From the outset, I had a fairly clear idea of how this should work based on
past experiences, but at first I took for granted that the other developers
would see things the same way I did, and I wasn’t necessarily consistent
myself. For a while we had several different patterns of communication,
depending on who had written the code and when. Every time you went to use
a component, it was pretty much a surprise which pattern it would use.</p>

<p>After one too many episodes of frustration, I realized that part of my job was
going to be to lay down the law about this — it wasn’t that my way was more
right than others, but rather that we needed to choose a way, or else reuse and
maintenance was going to become a nightmare. Here’s what I came up with:</p>

<ul>
<li><code>myComponent.set(key, value)</code> to change state (with the help of setter
methods from Dojo’s <a href="http://dojotoolkit.org/reference-guide/dijit/_Widget.html">dijit._Widget mixin</a>)</li>
<li><code>myComponent.on&amp;lt;Event&amp;gt;(componentEventData)</code> to announce state changes
and user interaction; Dojo lets us
<a href="http://dojotoolkit.org/reference-guide/dojo/connect.html">connect</a> to the
execution of arbitrary methods, so other pieces could listen for these
methods to be executed.</li>
<li><code>dojo.publish(topic, [ data ])</code> to announce occurrences of app-wide interest,
such as when the window is resized</li>
<li><code>myComponent.subscribe(topic)</code> to allow individual components react to
published topics</li>
</ul>


<p>Once we spelled out the patterns, the immediate benefit
wasn’t maintainability or reuse; rather, we found that we didn’t have to make
these decisions on a component-by-component basis anymore, and we could focus
on the questions that were actually unique to a component. With conventions
we could rely on, we were constantly discovering new ways to abstract and DRY
our code, and the consistency across components meant it was easier to work
with code someone else had written.</p>

<h2>Sanify asynchronicity</h2>

<p>One of the biggest challenges of JavaScript development — well, besides working
with the DOM — is managing the asynchronicity of it all. In the old system,
this was dealt with in various ways: sometimes a method would take a success
callback and a failure callback; other times a function would return an object
and check one of its properties on an interval.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">images</span> <span class="o">=</span> <span class="nx">toura</span><span class="p">.</span><span class="nx">sqlite</span><span class="p">.</span><span class="nx">getMedias</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="s2">&quot;image&quot;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">onGetComplete</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">images</span><span class="p">.</span><span class="nx">incomplete</span><span class="p">)</span>
</span><span class='line'>    <span class="k">return</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">clearInterval</span><span class="p">(</span><span class="nx">onGetComplete</span><span class="p">);</span>
</span><span class='line'>  <span class="nx">showImagesHelper</span><span class="p">(</span><span class="nx">images</span><span class="p">.</span><span class="nx">objs</span><span class="p">,</span> <span class="nx">choice</span><span class="p">)</span>
</span><span class='line'><span class="p">},</span><span class="mi">10</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>The problem here, of course, is that if <code>images.incomplete</code> never gets set to
false — that is, if the <code>getMedias</code> method fails — then the interval will never
get cleared. Dojo and now jQuery (since version 1.5) offer a facility for
handling this situation in an elegant and powerful way. In the new version of
the app, the above functionality looks something like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">toura</span><span class="p">.</span><span class="nx">app</span><span class="p">.</span><span class="nx">Data</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="err">‘</span><span class="nx">image</span><span class="err">’</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="nx">showImages</span><span class="p">,</span> <span class="nx">showImagesFail</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>The <code>get</code> method of <code>toura.app.Data</code> returns an <a href="http://www.sitepen.com/blog/2010/05/03/robust-promises-with-dojo-deferred-1-5/">immutable promise</a>
— the promise’s then method makes the resulting value of the asynchronous get
method available to <code>showImages</code>, but does not allow <code>showImages</code> to alter the
value. The promise returned by the get method can also be stored in a variable,
so that additional callbacks can be attached to it.</p>

<p>Using promises vastly simplifies asynchronous code, which can be one of the
biggest sources of complexity in a non-trivial application. By using promises,
we got code that was easier to follow, components that were thoroughly
decoupled, and new flexibility in how we responded to the outcome of an
asynchronous operation.</p>

<h2>Naming things is hard</h2>

<p>Throughout the course of the rewrite we were constantly confronted with one of
those pressing questions developers wrestle with: what should I name this
variable/module/method/thing? Sometimes I would find myself feeling slightly
absurd about the amount of time we’d spend naming a thing, but just recently
I was reminded how much power those names have over our thinking.</p>

<p>Every application generated by the Toura CMS consists of a set of “nodes,”
organized into a hierarchy. With the exception of pages that are standard
across all apps, such as the search page, the base content type for a page
inside APP is always a node — or rather, it was, until the other day. I was
working on a new feature and struggling to figure out how I’d display a piece
of content that was unique to the app but wasn’t really associated with a node
at all. I pored over our existing code, seeing the word node on what felt like
every other line. As an experiment, I changed that word node to baseObj in
a few high-level files, and suddenly a whole world of solutions opened up to me
— the name of a thing had limiting my thinking.</p>

<p>The lesson here, for me, is that the time we spent (and spend) figuring out
what to name a thing is not lost time; perhaps even more importantly, the goal
should be to give a thing the most generic name that still conveys what the
thing’s job — in the context in which you’ll use the thing — actually is.</p>

<h2>Never write large apps</h2>

<p>I touched on this earlier, but if there is one lesson I take from every large
app I’ve worked on, it is this:</p>

<blockquote><p>The secret to building large apps is never build large apps. Break up your
applications into small pieces. Then, assemble those testable, bite-sized
pieces into your big application. - Justin Meyer</p></blockquote>

<p>The more tied components are to each other, the less reusable they will be, and
the more difficult it becomes to make changes to one without accidentally
affecting another. Much like we had a manifesto of sorts for communication
among components, we strived for a clear delineation of responsibilities among
our components. Each one should do one thing and do it well.</p>

<p>For example, simply rendering a page involves several small, single-purpose
components:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">nodeRoute</span><span class="p">(</span><span class="nx">route</span><span class="p">,</span> <span class="nx">nodeId</span><span class="p">,</span> <span class="nx">pageState</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">pageState</span> <span class="o">=</span> <span class="nx">pageState</span> <span class="o">||</span> <span class="p">{};</span>
</span><span class='line'>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">nodeModel</span> <span class="o">=</span> <span class="nx">toura</span><span class="p">.</span><span class="nx">app</span><span class="p">.</span><span class="nx">Data</span><span class="p">.</span><span class="nx">getModel</span><span class="p">(</span><span class="nx">nodeId</span><span class="p">),</span>
</span><span class='line'>      <span class="nx">page</span> <span class="o">=</span> <span class="nx">toura</span><span class="p">.</span><span class="nx">app</span><span class="p">.</span><span class="nx">UI</span><span class="p">.</span><span class="nx">getCurrentPage</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">nodeModel</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">toura</span><span class="p">.</span><span class="nx">app</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">home</span><span class="p">();</span>
</span><span class='line'>    <span class="k">return</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">page</span> <span class="o">||</span> <span class="o">!</span><span class="nx">page</span><span class="p">.</span><span class="nx">node</span> <span class="o">||</span> <span class="nx">nodeId</span> <span class="o">!==</span> <span class="nx">page</span><span class="p">.</span><span class="nx">node</span><span class="p">.</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">page</span> <span class="o">=</span> <span class="nx">toura</span><span class="p">.</span><span class="nx">app</span><span class="p">.</span><span class="nx">PageFactory</span><span class="p">.</span><span class="nx">createPage</span><span class="p">(</span><span class="s1">&#39;node&#39;</span><span class="p">,</span> <span class="nx">nodeModel</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">page</span><span class="p">.</span><span class="nx">failure</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">toura</span><span class="p">.</span><span class="nx">app</span><span class="p">.</span><span class="nx">Router</span><span class="p">.</span><span class="nx">back</span><span class="p">();</span>
</span><span class='line'>      <span class="k">return</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>    <span class="nx">toura</span><span class="p">.</span><span class="nx">app</span><span class="p">.</span><span class="nx">UI</span><span class="p">.</span><span class="nx">showPage</span><span class="p">(</span><span class="nx">pf</span><span class="p">,</span> <span class="nx">nodeModel</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">page</span><span class="p">.</span><span class="nx">init</span><span class="p">(</span><span class="nx">pageState</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// record node pageview if it is node-only</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">nodeId</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nx">pageState</span><span class="p">.</span><span class="nx">assetType</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">dojo</span><span class="p">.</span><span class="nx">publish</span><span class="p">(</span><span class="s1">&#39;/node/view&#39;</span><span class="p">,</span> <span class="p">[</span> <span class="nx">route</span><span class="p">.</span><span class="nx">hash</span> <span class="p">]);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The router observes a URL change, parses the parameters for the route from the
URL, and passes those parameters to a function. The Data component gets the
relevant data, and then hands it to the PageFactory component to generate the
page. As the page is generated, the individual components for the page are also
created and placed in the page. The PageFactory component returns the generated
page, but at this point the page is not in the DOM. The UI component receives
it, places it in the DOM, and handles the animation from the old page to the
new one.</p>

<p>Every step is its own tiny app, making the whole process tremendously testable.
The output of one step may become the input to another step, but when input and
output are predictable, the questions our tests need to answer are trivial:
“When I asked the Data component for the data for node123, did I get the data
for node123?”</p>

<p>Individual UI components are their own tiny apps as well. On a page that
displays a videos node, we have a video player component, a video list
component, and a video caption component. Selecting a video in the list
announces the selection via the list’s onSelect method. Dojo allows us to
connect to the execution of object methods, so in the page controller, we have
this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="k">this</span><span class="p">.</span><span class="nx">connect</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">videoList</span><span class="p">,</span> <span class="s1">&#39;onSelect&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">assetId</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">video</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="err">\</span><span class="nx">_videoById</span><span class="p">(</span><span class="nx">assetId</span><span class="p">);</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">videoCaption</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;content&#39;</span><span class="p">,</span> <span class="nx">video</span><span class="p">.</span><span class="nx">caption</span> <span class="o">||</span> <span class="s1">&#39;&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">videoPlayer</span><span class="p">.</span><span class="nx">play</span><span class="p">(</span><span class="nx">assetId</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>The page controller receives the message and passes it along to the other
components that need to know about it — components don’t communicate directly
with one another. This means the component that lists the videos can list
anything, not just videos — its only job is to announce a selection, not to do
anything as a result.</p>

<h2>Keep rewriting</h2>

<blockquote><p>It takes confidence to throw work away … When people first start drawing,
they’re often reluctant to redo parts that aren’t right … they convince
themselves that the drawing is not that bad, really — in fact, maybe they meant
it to look that way. - <a href="http://www.paulgraham.com/taste.html">Paul Graham, “Taste for Makers”</a></p></blockquote>

<p>The blank slate offered by a rewrite allows us to fix old mistakes, but
inevitably we will make new ones in the process. As good stewards of our code,
we must always be open to the possibility of a better way of doing a thing. “It
works” should never be mistaken for “it’s done.”</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A new chapter]]></title>
    <link href="http://rmurphey.com/blog/2011/05/31/a-new-chapter/"/>
    <updated>2011-05-31T00:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/05/31/a-new-chapter</id>
    <content type="html"><![CDATA[<p>It was three years ago this summer that I <a href="http://blog.rebeccamurphey.com/2-years-in-some-thoughts-on-working-for-mysel">got the call, bought the Yuengling, smoked the cigarettes</a>, and began life as an independent consultant. It&rsquo;s been (almost) three years of ups and downs, and, eventually, among the most rewarding experiences of my life. Day by day, I wrote my own job description, found my own clients, set my own schedule, and set my own agenda.</p>




<p>Starting tomorrow, it&rsquo;s time for a new chapter in my working life: I&rsquo;ll be joining <a href="http://toura.com">Toura Mobile</a> full-time as their lead JavaScript developer, continuing my work with them on creating a PhoneGap- and Dojo-based platform for the rapid creation of content-rich mobile applications.</p>




<p>I&rsquo;ve been working with Toura for about six months now, starting shortly after I met <a href="http://twitter.com/MattRogish">Matt Rogish</a>, their director of development, at a JavaScript event in New York. They brought me on as a consultant to review their existing application, and the eventual decision was to rewrite it from the ground up, using the lessons learned and knowledge gained from the first version to inform the second. It was a risky decision, but it&rsquo;s paid off: earlier this year, Toura started shipping apps built with the rewritten system, and the care we took to create modular, loosely coupled components from the get-go has paid off immensely, meeting current needs while making it easier to develop new features. With the rewrite behind us, these days we&rsquo;re using the solid foundation we built to allow users of the platform to create ever more customized experiences in their applications.</p>




<p>If you know me at all, you know that I&rsquo;ve been pretty die-hard about being an independent consultant, so you might think this was a difficult decision. Oddly, it wasn&rsquo;t &mdash; I&rsquo;ve enjoyed these last several months immensely, the team I work with is fantastic, and I&rsquo;ve never felt more proud of work I&rsquo;ve done. Whenever I found myself wondering whether Toura might eventually tire of paying my consulting rates, I&rsquo;d get downright mopey. Over the course of three years, I&rsquo;ve worked hard for all of my clients, but this is the first time I&rsquo;ve felt so invested in a project&rsquo;s success or failure, like there was a real and direct correlation between my efforts and the outcome. It&rsquo;s a heady feeling, and I hope and expect it to continue for a while.</p>




<p>By the way, I&rsquo;ll be talking about the rewrite at both <a href="http://2011.texasjavascript.com">TXJS</a> and <a href="http://gothamjs.com">GothamJS</a> in the next few weeks.</p>




<p>Also: <a href="http://toura.com/about/jobs/">we&rsquo;re hiring</a> :)</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting Better at JavaScript]]></title>
    <link href="http://rmurphey.com/blog/2011/05/20/getting-better-at-javascript/"/>
    <updated>2011-05-20T00:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/05/20/getting-better-at-javascript</id>
    <content type="html"><![CDATA[<p>I seem to be getting a lot of emails these days asking a deceptively simple
question: “How do I get better at JavaScript?” What follows are some
semi-random thoughts on the subject:</p>

<p>The thing that I’ve come to realize about these questions is that some things
just take time. I wish I could write down “Ten Things You Need to Know to Make
You Amazing at the JavaScript,” but it doesn’t work that way. Books are
fantastic at exposing you to guiding principles and patterns, but if your brain
isn’t ready to connect them with real-world problems, it won’t.</p>

<p><strong>The number one thing that will make you better at writing JavaScript is writing
JavaScript.</strong> It’s OK if you cringe at it six months from now. It’s OK if you
know it could be better if you only understood X, Y, or Z a little bit better.
<a href="http://www.paulgraham.com/taste.html"> Cultivate dissatisfaction </a>, and fear the day when you aren’t disappointed with
the code you wrote last month.</p>

<p>Encounters with new concepts are almost always eventually rewarding, but in the
short term I’ve found they can be downright demoralizing if you’re not aware of
the bigger picture. The first step to being better at a thing is realizing you
could be better at that thing, and initially that realization tends to involve
being overwhelmed with all you don’t know. The first <a href="http://jsconf.us/2009/"> JSConf </a>, in 2009, was
exactly this for me. I showed up eager to learn but feeling pretty cocky about
my skills. I left brutally aware of the smallness of my knowledge, and it was a
transformational experience: getting good at a thing involves seeking out
opportunities to feel small.</p>

<p>One of the most helpful things in my learning has been having access to smart
people who are willing to answer my questions and help me when I get stuck.
Meeting these people and maintaining relationships with them is hard work, and
it generally involves interacting with them in real life, not just on the
internet, but the dividends of this investment are unfathomable.</p>

<p>To that end, attend conferences. Talk to the speakers and ask them questions.
Write them emails afterwards saying that it was nice to meet them. Subscribe to
their blogs. Pay attention to what they’re doing and evangelize their good
work.</p>

<p>Remember, too, that local meetups can be good exposure to new ideas too, even
if on a smaller scale. The added bonus of local meetups is that the people
you’ll meet there are … local! It’s easy to maintain relationships with them
and share in learning with them in real life.</p>

<p>(An aside: If your company won’t pay for you to attend any conferences, make
clear how short-sighted your company’s decision is and start looking for a new
job, because your company does not deserve you. Then, if you can, cough up the
money and go anyway. As a self-employed consultant, I still managed to find
something like $10,000 to spend on travel- and conference-related expenses last
year, and I consider every penny of it to be money spent on being better at
what I do. When I hear about big companies that won’t fork over even a fraction
of that for an employee who is raising their hand and saying “help me be better
at what I do!”, I rage.)</p>

<p>Make a point of following the bug tracker and repository for an active
open-source project. Read the bug reports. Try the test cases. Understand the
commits. I admit that I have never been able to make myself do this for
extended periods of time, but I try to drop in on certain projects now and then
because it exposes me to arbitrary code and concepts that I might not otherwise
run into.</p>

<p>Read the source for your favorite library, and refer to it when you need to
know how a method works. Consult the documentation when there’s some part of
the source you don’t understand. When choosing tools and plugins, read the
source, and see whether there are things you’d do differently.</p>

<p>Eavesdrop on communities, and participate when you have something helpful to
add. Lurk on a mailing list or a forum or in an IRC channel, help other people
solve problems. If you’re not a <a href="http://slash7.com/2006/12/22/vampires/"> help vampire </a> — if you give more than you take —
the “elders” of a community will notice, and you will be rewarded with their
willingness to help you when it matters.</p>

<p>Finally, books:</p>

<ul>
<li>JavaScript: The Good Parts, by Douglas Crockford. It took me more than one
try to get through this not-very-thick book, and it is not gospel. However,
it is mandatory reading for any serious JavaScript developer.</li>
<li><a href="http://eloquentjavascript.net/"> Eloquent JavaScript </a>, Marijn Haverbeke (also in print). This is another book
that I consider mandatory; you may not read straight through it, but you
should have it close at hand. I like it so much that I actually bought the
print version, and then was lucky enough to get a signed copy from Marijn at
JSConf 2011.</li>
<li>JavaScript Patterns, by Stoyan Stefanov. This was the book that showed me
there were names for so many patterns that I’d discovered purely through
fumbling around with my own code. I read it on the flight to the 2010 Boston
jQuery Conference, and it’s definitely the kind of book that I wouldn’t have
gotten as much out of a year earlier, when I had a lot less experience with
the kinds of problems it addresses.</li>
<li>Object-Oriented JavaScript, by Stoyan Stefanov. It’s been ages since I read
this book, and so I confess that I don’t have a strong recollection of it,
but it was probably the first book I read that got me thinking about
structuring JavaScript code beyond the “get some elements, do something with
them” paradigm of jQuery.</li>
</ul>


<p>Good luck.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Objects as Arguments: Where do you draw the line?]]></title>
    <link href="http://rmurphey.com/blog/2011/04/25/objects-as-arguments/"/>
    <updated>2011-04-25T11:16:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/04/25/objects-as-arguments</id>
    <content type="html"><![CDATA[<p>I was reviewing some code last week and came across a snippet that looked a lot like this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">someObject</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>  <span class="c1">// ...</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">onSuccess</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// ...</span>
</span><span class='line'>    <span class="k">this</span><span class="p">.</span><span class="nx">someMethod</span><span class="p">(</span><span class="nx">resp</span><span class="p">.</span><span class="nx">token</span><span class="p">,</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">host</span><span class="p">,</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">key</span><span class="p">,</span> <span class="nx">resp</span><span class="p">.</span><span class="nx">secret</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">someMethod</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">host</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">secret</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// ...</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>My immediate response was to suggest that it didn&#8217;t make sense to be passing
four separate arguments to <code>someMethod</code>, especially when the arguments were
being &#8220;unpacked&#8221; from an already-existing object. Certainly we could just pass
the <code>resp</code> object directly to <code>someMethod</code>, and let <code>someMethod</code> unpack it as
necessary &#8211; we&#8217;d save some bytes, and we&#8217;d also leave ourselves some room to
grow. &#8220;I&#8217;m not a big fan of functions that take four arguments,&#8221; I said in my
GitHub comment.</p>

<p>To the original author&#8217;s credit, &#8220;because I say so&#8221; wasn&#8217;t sufficient reason to
rewrite code that was working just fine, thank you very much. If four arguments
was too many, was two arguments too many? Why draw the line at four? Surely the
four-argument signature helped indicate to future developers what was required
in order for the function to &#8230; function. Right? My hackles momentarily
raised, I parried by pointing out that if the arguments were actually required
by the function, maybe the function ought to actually check for their presence
before using them. Ha! While the original author was distracted by my disarming
logic, I fretted over the fact that I use a function that take four arguments
every day: <code>dojo.connect(node, 'click', contextObj, 'handlerMethod')</code>. Ohnoes.</p>

<p>So where do you draw the line? Certainly you could write that <code>dojo.connect</code>
call like so:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">dojo</span><span class="p">.</span><span class="nx">connect</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">node</span> <span class="o">:</span> <span class="nx">node</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">event</span> <span class="o">:</span> <span class="s1">&#39;click&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">context</span> <span class="o">:</span> <span class="nx">contextObj</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">method</span> <span class="o">:</span> <span class="s1">&#39;handlerMethod&#39;</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>This, though, might make you poke your eyes out. It certainly isn&#8217;t as concise
as the four-argument approach, and it makes a lot of things like
<a href="http://ejohn.org/blog/partial-functions-in-javascript/">partial</a>
<a href="http://dojotoolkit.org/reference-guide/dojo/partial.html#dojo-partial">application</a>
a lot harder. Clearly there&#8217;s more to this than &#8220;if there&#8217;s more than four
arguments, put them in an object&#8221; &#8230; but what are the rules?</p>

<h2>Optional Arguments</h2>

<p>Probably the most compelling reason to use an object is when there are several
optional arguments. For example, last fall I was reviewing some code from a
potential training client, and I came across this:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">addBling</span><span class="p">(</span><span class="s1">&#39;#awesome&#39;</span><span class="p">,</span> <span class="s1">&#39;fuchsia&#39;</span><span class="p">,</span> <span class="s1">&#39;slow&#39;</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">&#39;done!&#39;</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>No one can argue that this is not terrible, and yet every experienced
JavaScript developer knows how the developer(s) who wrote it arrived there. At
first, the function needed three arguments, and all was good with the world.
But then, it seemed like the same function could be used to do another thing by
just passing two more arguments &#8211; no big deal, because if those two arguments
weren&#8217;t present, then just the first three would suffice. Five arguments
certainly isn&#8217;t <em>that</em> bad, right? After that, though, things went south: for
whatever undoubtedly marketing-department-driven reason, suddenly both the
original three-argument case and the later five-argument case both needed to
receive two more arguments, and these two new arguments were mandatory. Now
both cases had seven-argument signatures, and in some cases, two of those seven
arguments needed to be null so nothing would break.</p>

<p>This case demonstrates the most compelling reason to switch to using an object
instead: optional arguments. When the developer discovered that the original,
three-argument <code>addBling</code> could be used for the five-argument case as well, it
was probably time to refactor:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// original</span>
</span><span class='line'><span class="nx">addBling</span><span class="p">(</span><span class="s1">&#39;#awesome&#39;</span><span class="p">,</span> <span class="s1">&#39;fuchsia&#39;</span><span class="p">,</span> <span class="s1">&#39;slow&#39;</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// new hotness</span>
</span><span class='line'><span class="nx">addBling</span><span class="p">(</span><span class="s1">&#39;#awesome&#39;</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">color</span> <span class="o">:</span> <span class="s1">&#39;fuchsia&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">speed</span> <span class="o">:</span> <span class="s1">&#39;slow&#39;</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then, the same function could be used while passing it more information about
how to behave in the five-argument case:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">addBling</span><span class="p">(</span><span class="s1">&#39;#omgSoAwesome&#39;</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">color</span> <span class="o">:</span> <span class="s1">&#39;fuchsia&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">speed</span> <span class="o">:</span> <span class="s1">&#39;slow&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">unicorns</span> <span class="o">:</span> <span class="mi">3</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">rainbows</span> <span class="o">:</span> <span class="mi">5</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Then, when it came time to add yet more bling, the function signature wouldn&#8217;t need to change,</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">addBling</span><span class="p">(</span><span class="s1">&#39;#awesome&#39;</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">color</span> <span class="o">:</span> <span class="s1">&#39;fuchsia&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">speed</span> <span class="o">:</span> <span class="s1">&#39;slow&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">timesToBlink</span> <span class="o">:</span> <span class="mi">3</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">alertOnSuccess</span> <span class="o">:</span> <span class="s1">&#39;done!&#39;</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">addBling</span><span class="p">(</span><span class="s1">&#39;#omgSoAwesome&#39;</span><span class="p">,</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">color</span> <span class="o">:</span> <span class="s1">&#39;purple&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">speed</span> <span class="o">:</span> <span class="s1">&#39;fast&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">unicorns</span> <span class="o">:</span> <span class="mi">3</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">rainbows</span> <span class="o">:</span> <span class="mi">5</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">timesToBlink</span> <span class="o">:</span> <span class="mi">9001</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">alertOnSuccess</span> <span class="o">:</span> <span class="s1">&#39;woohoo!&#39;</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Extensibility and Future-Proofing</h2>

<p>Another case for passing in an object is when you want the flexibility that an
object provides, even if your code doesn&#8217;t require it for now:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">Person</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">firstName</span> <span class="o">=</span> <span class="nx">args</span><span class="p">.</span><span class="nx">firstName</span><span class="p">;</span>
</span><span class='line'>  <span class="k">this</span><span class="p">.</span><span class="nx">lastName</span> <span class="o">=</span> <span class="nx">args</span><span class="p">.</span><span class="nx">lastName</span><span class="p">;</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>For now, you only want to be able to provide the first and last name of the
person &#8211; it would work just fine to create a function signature for the
<code>Person</code> constructor that took exactly those two arguments, because indeed they
are required. On the other hand, though, this is incredibly short-sighted &#8211;
while first and last name may be all that you care about now, there&#8217;s obviously
more to a person than those two attributes, and eventually you may want to
provide attributes such as age, occupation, etc. Doing this with individual
arguments quickly becomes unsustainable. Besides that, though, it also makes
assigning instance properties a pain in the ass. By passing an object, we can
rewrite the above code as such:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">Person</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">args</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">dojo</span><span class="p">.</span><span class="nx">mixin</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">args</span><span class="p">);</span>
</span><span class='line'>  <span class="c1">// jQuery: $.extend(this, args);</span>
</span><span class='line'>  <span class="k">return</span> <span class="k">this</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>Now &#8211; assuming this is what we want &#8211; we can mix in <em>any</em> settings we provide
in the <code>args</code> argument. Dojo, for example, bakes this ability in to anything
that inherits from <code>dijit._Widget</code>:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">thinger</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">my</span><span class="p">.</span><span class="nx">Thinger</span><span class="p">({</span>
</span><span class='line'>  <span class="nx">title</span> <span class="o">:</span> <span class="s1">&#39;Favorite Animals&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nx">animals</span> <span class="o">:</span> <span class="p">[</span> <span class="s1">&#39;Narwhal&#39;</span><span class="p">,</span> <span class="s1">&#39;Lemur&#39;</span><span class="p">,</span> <span class="s1">&#39;Honey Badger&#39;</span> <span class="p">]</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<h2>Use Objects for Related Data</h2>

<p>An important qualifier here is that all of the properties of an object that
we&#8217;ve talked about passing to our <code>Person</code> constructor are related &#8211; they all
are saying something about the Person you&#8217;re creating. What if creating our
Person was asynchronous, and we wanted to run a function once our Person was
created? In a (contrived) case like that, I think it does make sense to pass in
a separate argument:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="k">new</span> <span class="nx">Person</span><span class="p">(</span><span class="nx">configObj</span><span class="p">,</span> <span class="nx">fn</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>In this particular example, we still only have two arguments &#8211; we haven&#8217;t
wandered into that muddy realm of four or more. That said, I think this
distinction is part of what makes <code>dojo.connect(node, 'click', contextObj,
'handlerMethod')</code> OK: the arguments are four distinctly different types of
information. Taken together, they have an almost narrative quality: when this
node receives a click, use the context object&#8217;s <code>handlerMethod</code>. A signature
like <code>new Person('Rebecca', 'Murphey', 34, 'web developer', 2 /*cats*/, 2
/*dogs*/)</code> doesn&#8217;t <em>feel</em> the same as the <code>dojo.connect</code> example &#8211; it&#8217;s
information that&#8217;s too related to be expressed as independent arguments.</p>

<h2>Four or More, Time to Refactor?</h2>

<p>I think the bottom line here is a) it&#8217;s complicated, and b) if your function
signature has four or more arguments, you should almost certainly consider
whether there&#8217;s a better way to do it. If the arguments are super-related, it
may be they belong in an object, so you get the benefit of easy extensibility
down the road. If there are optional arguments, you almost certainly want to
wrap those in an object to avoid passing <code>null</code> over and over again.</p>

<p>Personally, my threshold is actually closer to two arguments &#8211; if I find
myself wanting a third argument, I question whether my function is trying to do
more than it should be doing &#8211; maybe I should do some pre-processing of the
input so I can get away with just passing in two arguments. Every additional
argument is an indication of additional complexity, which means an additional
opportunity for things to go wrong.</p>

<h2>Other Considerations</h2>

<p>I posed this question to
<a href="http://twitter.com/#!/rmurphey/status/62172041037623296">Twitter</a> and got a
ton of interesting feedback. Here are some of the highlights that I didn&#8217;t
cover above:</p>

<ul>
<li><a href="https://twitter.com/raydaly/status/62320791232069632">@raydaly</a> no new nouns
is my principle. If unrelated data needs to be passed, diff args.</li>
<li><a href="https://twitter.com/dadaxl/status/62308649699250176">@dadaxl</a> I would pass
an obj if I&#8217;ve a dynamic bunch of args containing functions.</li>
<li><a href="https://twitter.com/sh1mmer/status/62308597153021952">@sh1mmer</a> omg! Objects
for the love of god! No one likes immutable APIs. Just ask @ls_n</li>
<li><a href="https://twitter.com/mattrogish/status/62307288597266432">@MattRogish</a> Rails
tends to do required things are named args, optional things are a hash</li>
<li><a href="https://twitter.com/ryanflorence/status/62511600837468161">@ryanflorence</a>
obfuscation often influences me, objects don&#8217;t compress as well as multiple
args.</li>
<li><a href="https://twitter.com/getify/status/62512606132449280">@getify</a> if more than
half of the args are optional&#8230;or if there are several boolean params which
without names can be confusing</li>
<li><a href="https://twitter.com/jcoglan/status/62253184369954816">@jcoglan</a> When further
args are optional, or args.length&gt;3. Need to spot when options merit a
refactoring, though.</li>
<li><a href="https://twitter.com/digitalicarus/status/62247330354692096">@digitalicarus</a>
A combo of sheer length, amount of reuse, if it&#8217;s an API, and/or if it&#8217;s
designed to be called a variety of ways to a similar end.</li>
<li><a href="https://twitter.com/bryanforbes/status/62237053148086272">@BryanForbes</a> If I
have to start swapping arguments and type checking, it&#8217;s time for one object
or reworking my function.</li>
<li><a href="https://twitter.com/myfreeweb/status/62229278581993472">@myfreeweb</a> I use an
object when I start forgetting the order of args &#8230; or there is no logical
order like (key, value, callback) at all</li>
<li><a href="https://twitter.com/zetafleet/status/62209835097268224">@zetafleet</a> When
many of the arguments are optional or they&rsquo;re all getting stored or
copied directly over to the object.</li>
<li><a href="https://twitter.com/maravillas/status/62176422877335552">@maravillas</a> I
usually don&#8217;t make an obj just for passing data; if arglist is too long,
maybe the function does too much and needs refactoring.</li>
</ul>


<h2>Postscript</h2>

<p>We ended up leaving the code that spurred this whole conversation exactly as it
was.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Modern JavaScript]]></title>
    <link href="http://rmurphey.com/blog/2011/04/15/modern-javascript/"/>
    <updated>2011-04-15T11:16:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/04/15/modern-javascript</id>
    <content type="html"><![CDATA[<p>My presentation <a href="http://www.slideshare.net/rmurphey/the-jquery-divide-5287573">the jQuery Divide</a> (<a href="http://jsconf.eu/2010/speaker/the_jquery_divide_by_rebecca_m.html">video here</a>) has been <a href="http://news.ycombinator.com/item?id=2429411">making the rounds</a> on the internet again, six months after I delivered it at JSConf.eu in Berlin, and this time around, a colleague on IRC shared a link with me that drew from it: <a href="http://www.dagolden.com/index.php/1446/is-javascript-the-new-perl/">Is JavaScript the New Perl?</a></p>

<p>Perl has a special place in my heart; it&#8217;s the first language I used to solve a real-world problem, and I still have the second edition Learning Perl that my good friend Marcus got for me at the time. These days I struggle for it not to look mostly like a lot of gibberish, but in the late 1990s it was funtimes.</p>

<p>Anyway. The post that linked to my presentation asked if JavaScript might be going through some of the same pains that Perl has gone through, and linked to an eerily relevant presentation about Modern Perl, a movement &#8220;actively seeks to both to teach how to write good code and change perceptions of Perl that still linger from the dot.com 90s.&#8221; It talks about the void that Perl sought to fill way back in 1987, and then steps through the highs and lows of the intervening 23 years.</p>

<p>One thing that struck me, reading the slides, is that Perl &#8211; like other open-source, server-side languages &#8211; has the distinct benefit of being community-driven. While, yes, JavaScript has a wonderful and vibrant community, the language itself is held hostage by browser vendors, some of whom have shown a strong inclination to not give a fuck about owning up to and fixing their egregious mistakes. Using new features of a language like Perl is, at the end of the day, a largely internal problem &#8211; given enough time and money, switching to a new version of the language that offers new features for code organization, testing, and abstraction is a thing a project can do. Indeed, Perl as a community can even make bold decisions like deciding that a new version simply won&#8217;t be back-compat with a version that came before, throwing away ideas that turned out to be duds; meanwhile, JavaScript web developers often must bend over backwards to ensure back-compat with decade-old technology, and the only way to transition away from that technology is to give up on a set of users entirely.</p>

<p>We&#8217;ve already seen what this means for JavaScript as a language: it was years after JavaScript&#8217;s debut before we really started seeing <a href="http://www.yuiblog.com/blog/2007/06/12/module-pattern/">conversations</a> about what a module should look like in JavaScript, and <a href="http://tagneto.blogspot.com/2011/04/on-inventing-js-module-formats-and.html">we&#8217;re still fighting over it</a> today. Without a solid dependency management system &#8211; something you can take for granted in any 15-year-old community-driven language &#8211; dependency management often means sticking another script tag on the page, and even the most popular JavaScript library on the planet <a href="http://bugs.jquery.com/ticket/7102">struggles</a> with how to participate in a fledgling ecosystem. With no arbiter of common, tested, community-approved, community-vetted solutions &#8211; see Perl&#8217;s CPAN &#8211; it&#8217;s an environment that&#8217;s ripe for fragmentation, and shining examples of <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">Not Invented Here (NIH)</a> litter the JavaScript landscape. Lacking even an agreed-upon method of expressing dependencies, the <em>findability</em> of good solutions is low, and coalescence only occurs around tools with extremely low barriers to entry and extremely high near-term reward.</p>

<p>When Marcus was teaching me Perl, back in the dot com heyday of the late 1990s and before the world temporarily went to hell for a few years, there was great emphasis on TIMTOWTDI: there is more than one way to do it. That mantra made Perl beautiful and elegant and powerful. Too often, it also made it ridiculously hard for the next developer to build upon and maintain, especially as the problems developers were solving got more complicated than copying and pasting some code to support a contact form (sound familiar?). In the end, that mantra meant Perl&#8217;s reputation suffered, as the consequences of code written by developers with a whole lot of freedom and not so much skill became clear.</p>

<p>This, in a nutshell, is what I was talking about in Berlin: that the reputation of this language we love stands to suffer if we don&#8217;t get around to working together to solve these larger problems, and educating the wider world of JavaScript developers as we figure it out. Unlike with Perl, the language itself isn&#8217;t going to evolve in time to help us here &#8211; unless and until we&#8217;re willing to give up on huge swaths of users, we will, generously, be <a href="http://infrequently.org/2010/09/but-ie-9-is-just-around-the-corner/">stuck with the browser technology of 2009</a> for a long time to come. Unlike the Modern Perl movement, <strong>the patterns and tools and practices that will form the foundation of Modern JavaScript are going to have to come from outside implementations of the language itself</strong>.</p>

<p>Realizing that, it becomes clear just how imperative it is that we, as a community, figure out dependency management, modularization, and intentional interoperability so that these patterns, tools, and practices can start to emerge organically. James Burke, the creator of <a href="http://requirejs.org/">RequireJS</a>, is something of a hero to me, not for creating RequireJS, but for taking on the challenge of interacting calmly and level-headedly with all sorts of stakeholders to try to make <a href="http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition">AMD modules</a> a viable reality. Tool and library developers need to stop debating whether this is a good idea and get to work on making it happen.</p>

<p>Tools and libraries also need to take seriously the need for modularization &#8211; though I confess I have many misgivings about the NIH aspect of Dustin Diaz&#8217;s <a href="https://github.com/ender-js/Ender">Ender.js</a>, and wish that the considerable effort involved had been directed toward an established project with similar features, I can&#8217;t help but hope it will pressure libraries like jQuery to make more efforts in the direction of modularization.</p>

<p>An equally important aspect of modularization is ensuring minimal duplication of effort. As a community, we need to agree on a core set of functionality that ought to be provided by the language but isn&#8217;t, and implement that itself as an interchangeable module. A page with both Underscore.js and jQuery on it has tremendous duplication of functionality, for example. Interchangeability will allow end users to roll exactly the tool they need, no more and no less. Eventually, standard toolkits could emerge that draw on the best of all worlds, rather than one-size-fits-all tools that exist in isolation.</p>

<p>While I agree with what Tom Dale wrote in his oddly controversial post &#8211; that <a href="http://tomdale.net/2011/04/imagine-a-beowulf-cluster-of-javascript-frameworks/">&#8220;unless it is designed to work well together, it usually won&rsquo;t&#8221;</a> &#8211; the more I think about it, the more I realize that the problem lies in our current inability to reliably isolate functionality and express dependencies across tools. It&#8217;s not that large tools like Dojo are the One True Way &#8211; it&#8217;s that large tools like Dojo are incredibly powerful precisely because they take seriously the need for a lightweight core leveraged by components that deliver specific, isolated functionality. JavaScript as a whole will become more powerful by embracing the pattern.</p>

<p>The political problems here are obvious and several: such modularization will, by definition, lead to winners and losers; the identities of libraries as we know them stand to be diluted if it becomes trivial to use only parts of them. The emphasis will shift to curated toolkits that assemble best-of-breed solutions, and NIH efforts will compete on merit, not marketing. At the same time, though, trying new things will no longer involve learning a whole new set of tools, and developers won&#8217;t be as stuck with a solution that made sense once upon a time but not anymore.</p>

<p>A final and important piece of the puzzle is actually educating people about the patterns that are enabled when we embrace these tools and practices. The wider community of everyday devs who are just trying to get their job done has hopefully graduated from copying and pasting scripts, but there&#8217;s a long path ahead, and part of the work of Modern JavaScript needs to be clearing that path for them.</p>

<p>I said it in my Berlin talk, and I will say it again: <em>sharing what we know is as important as making new things</em>, even if it&#8217;s not always quite as fun. All the script loaders, build tools, inheritance systems, array utilities, templating frameworks, and data abstractions in the world are meaningless if we don&#8217;t help people understand how and why to use them.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Dojo Boilerplate]]></title>
    <link href="http://rmurphey.com/blog/2011/04/04/a-dojo-boilerplate/"/>
    <updated>2011-04-04T00:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/04/04/a-dojo-boilerplate</id>
    <content type="html"><![CDATA[<p>When I first started playing with the <a href="http://dojotoolkit.org">Dojo Toolkit</a>, it was easy enough to <a href="http://dojotoolkit.org/documentation/tutorials/1.6/hello_dojo/">use the CDN-hosted <code>dojo.js</code> and get started</a>, but before long I wanted to make use of one of the features that drew me to Dojo in the first place: the build system that parses your code&rsquo;s dependencies as expressed by <code>dojo.require()</code> statements and creates production-ready files.</p>


<p>Coming from a world where this was entirely a DIY affair, the patterns I should follow for taking advantage of Dojo&rsquo;s system were, shall we say, less than clear. There was a lot of frustration, a lot of swearing, and a lot of pleas for help in #dojo on Freenode.</p>


<p>These days, I&rsquo;m talking about Dojo a lot, and I&rsquo;ve gotten pretty comfortable with how to set up a project &mdash; I even wrote a post about <a href="http://blog.rebeccamurphey.com/scaffolding-a-buildable-dojo-application">scaffolding a Dojo app</a> once I felt like I had the basics down &mdash; but for a long time I&rsquo;ve wanted to release a ready-made starter project, rather than making people follow seven lengthy steps.</p>


<p>With the help of <a href="http://zetafleet.com">Colin Snover</a>, I&rsquo;m pleased to release the <a href="https://github.com/csnover/dojo-boilerplate">Dojo Boilerplate</a>, a simple starter project if you&rsquo;d like to get your feet wet with Dojo and the power of its dependency management and build system. It comes with a bare-bones do-nothing app, a shell script for downloading the Dojo SDK and getting it in the right place, and a shell script and profile file for actually creating a built version. For the brave, it also includes a work-in-progress router for single-page apps &mdash; one of the few features that I feel Dojo itself is missing. Everything you should need to know is documented in the README.</p>


<p>I&rsquo;ve also created a <a href="https://github.com/rmurphey/dojo-demo">small demo app</a> that uses the boilerplate and shows some of the basic concepts of MVC development using Dojo, including separating your code into models, views, controllers, and third-party services. It includes an example of templated widgets, which are one of the biggest selling points of Dojo for me, as well as an uber-basic example of object stores, new in Dojo 1.6.</p>


<p>The goal of the boilerplate and the demo app is to eliminate some of that pain and WTF that I went through &mdash; while Dojo is ridiculously powerful, the barrier to entry can seem daunting. Over and over again, though, I am grateful that I took the time to overcome it.</p>


<p>Finally: as always, pull requests and issues are welcome. Enjoy.</p>


<p>Update: Colin is now the maintainer of the boilerplate; I&#8217;ve updated the links above accordingly.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[When you're building a non-trivial JS application ...]]></title>
    <link href="http://rmurphey.com/blog/2011/03/30/when-you-re-building-a-non-trivial-js-application/"/>
    <updated>2011-03-30T00:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/03/30/when-you-re-building-a-non-trivial-js-application</id>
    <content type="html"><![CDATA[<p>I sense another round of discussion of this is <a href="http://twitter.com/slightlylate/status/52924409509445632">about to begin</a>, and 140 characters isn&#8217;t quite enough to say what I want to say, so:</p>


<p>When you&#8217;re building a non-trivial JS application, you don&#8217;t want a jQuery developer, or a Dojo developer, or a YUI developer, or, frankly, any developer who chooses their tool before they evaluate the problem. <strong>For god&#8217;s sake, you want a JavaScript developer.</strong> Can you roll your own solution with jQuery as the base? Yes! Should you? I don&#8217;t think so, and I advise my clients against it for reasons I&#8217;ve <a href="http://blog.rebeccamurphey.com/on-rolling-your-own">written about</a> <a href="http://blog.rebeccamurphey.com/on-jquery-large-applications">at length</a>, but I&#8217;m open to hearing compelling, articulate, fact-based arguments in favor of it!</p>


<p>But do me a favor, OK? Don&#8217;t base your arguments solely on the winner of a popularity contest. Don&#8217;t tell me how easy it is to find developers familiar with one library or another, because I&#8217;ll come right back and ask you just how good those developers will be at solving problems that aren&#8217;t addressed by said library. And please tell me you&#8217;ve at least explored some of the other options besides [insert the library you&#8217;re advocating here].&nbsp;</p>


<p>People read what I write about JavaScript libraries and they write me heartfelt tweets and e-mails saying OMG YOU HATE JQUERY NOW WHAT HAPPENEDDDDD? I don&#8217;t hate jQuery! It is a perfectly viable and valuable tool for so many things! But when people argue not just its viability but its absolute <em>supremacy</em>, when people get defensive and possibly even angry that I suggest there are solutions that are vastly better suited to a certain set of problems, when people contort themselves into pretzels to make their case and their case is &#8220;well, it&#8217;s not <em>that</em> bad&#8221; &#8230; well, that smacks of blind loyalty, not a thoughtful weighing of the tradeoffs and challenges we face as developers, and I question how those people would fare if actually confronted with the needs of a non-trivial application.&nbsp;</p>


<p>So, please: Tell me what solutions you&#8217;ve looked at for non-trivial application development. Tell me where they work, tell me where they fall short. Tell me what you&#8217;re working on and how you chose the tools. Don&#8217;t tell me why I&#8217;m wrong &#8211; tell me why you&#8217;re right. Deal? Discuss.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Future of jQuery Fundamentals (and a confession)]]></title>
    <link href="http://rmurphey.com/blog/2011/03/17/the-future-of-jquery-fundamentals-and-a-confession/"/>
    <updated>2011-03-17T00:00:00-04:00</updated>
    <id>http://rmurphey.com/blog/2011/03/17/the-future-of-jquery-fundamentals-and-a-confession</id>
    <content type="html"><![CDATA[<p>About 9 months ago, <a href="http://blog.rebeccamurphey.com/2010/06/17/open-source-jquery-training">I released</a> <a href="http://jqfundamentals.com/book/">jQuery Fundamentals</a>, a free, online training curriculum for people interested in learning jQuery based on material I&rsquo;d assembled while leading jQuery trainings.</p>




<p>The response was and has continued to be amazing: not only has the book seen hundreds of thousands of visits, but it has also received content contributions and bug reports from dozens of people. It has become something of a collaborative work, and one of the go-to resources for jQuery and beginning JavaScript learning. It has been used to teach classes internally at companies and at colleges and universities, and it&rsquo;s been translated into multiple languages. It&rsquo;s even made me a tad bit of money &mdash; I recently granted a license to Webucator to create derivative works for their <a href="http://www.webucator.com/webdesign/jquery.cfm">jQuery class</a> &mdash; and landed me near the top of Google&rsquo;s search results for &ldquo;jQuery training&rdquo;.</p>




<p>And so here is where we get to the confession part: while I&rsquo;ve stayed very much in touch with the evolution of jQuery these last couple of years, written gobs of sample code in efforts to make people better at using the library, and even played a bit of a role in some of the new features in jQuery 1.5, the last time I chose the library for a project was in the fall of 2008. The last time I used it on a project at all was in the summer of 2010, and in a matter of a few weeks I was gutting the fragile, bug-ridden, DOM-centric code and re-writing the single-page application with &mdash; wait for it! &mdash; Dojo. jQuery and I have gone from being in a committed relationship to seeing other people to pretty much just saying hi on Facebook now and again.</p>




<p>This has put me in a strange place with jQuery Fundamentals &mdash; I want to be investing my energy supporting projects that I <em>use</em>, and while I can still write jQuery just fine and stay in touch with what&rsquo;s going on with it, I really don&rsquo;t &hellip; <em>use</em> it. That&rsquo;s made it increasingly difficult to continue maintaining jQuery Fundamentals as a resource for the jQuery community.</p>




<h2>Burying the Lede</h2>




<p>At the jQuery conference in Boston last fall, John Resig invited me to participate in a conversation about an effort by the project to create a learning resource for the community, and through the course of that and future conversations, jQuery Fundamentals has found its new home.</p>




<p>I&rsquo;ve been working actively with jQuery team member (and <a href="http://yayquery.com">yayQuery</a> co-host) Adam J. Sontag and community member Dan Heberden to get the book into good shape as it transitions to being &ldquo;owned&rdquo; by the jQuery project. I&rsquo;ve also donated a third of the proceeds of the Webucator licensing arrangement to the jQuery project, to recognize the contributions of the community and to give even a wee bit of financial support to the learning efforts.</p>




<p>Adam, Dan, and I will be working hard to address some of the <a href="https://github.com/rmurphey/jqfundamentals/issues">open issues</a> with the book in the coming weeks. If you&rsquo;re interested in helping, drop me an email, hit me up on Twitter, or just submit a pull request (though you may want to talk to us first if the solution to an issue isn&rsquo;t straightforward). From formatting fixes to writing new content to updating the book to reflect the changes in jQuery 1.5, there&rsquo;s a lot to be done.</p>




<h2>What&rsquo;s Next?</h2>




<p>These days I&rsquo;m working with a fantastic client doing mobile application development with PhoneGap and Dojo. It&rsquo;s pretty much the most challenging, engaging, rewarding project I&rsquo;ve had an opportunity to work on in nearly three years of independent consulting. These days, when I get the very inquiries I hoped to get by releasing jQuery Fundamentals in the first place, I direct people to the excellent folks at <a href="http://bocoup.com">Bocoup</a>. Slowly, I&rsquo;m recalibrating my efforts and attention toward the projects that make my day-to-day development life better. As soon as I feel like jQuery Fundamentals is in a good place where I don&rsquo;t have to worry about its future, you can expect to see a lot more learning-related content coming from me again; just, this time, it probably won&rsquo;t be about jQuery.</p>




<p>I hope you&rsquo;ll stick around.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Deferreds coming to jQuery 1.5?]]></title>
    <link href="http://rmurphey.com/blog/2010/12/25/deferreds-coming-to-jquery/"/>
    <updated>2010-12-25T00:00:00-05:00</updated>
    <id>http://rmurphey.com/blog/2010/12/25/deferreds-coming-to-jquery</id>
    <content type="html"><![CDATA[<p><em>I have updated this post to show the code using the API that was released in jQuery 1.5.0.</em></p>

<p>A few weeks ago, a <a href="https://github.com/jquery/jquery/commit/ab3ba4a81252c4357a7aab5f24d765d41d47986e">major rewrite of jQuery&#8217;s Ajax functionality</a>
landed in the jQuery GitHub repo. Thanks to <a href="http://www.jaubourg.net/">Julian Aubourg</a>, jQuery looks like it will get a feature
that I&#8217;ve desperately wished it had ever since I started spending time with
Dojo:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">doAjax</span><span class="p">(</span><span class="nx">debug</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">req</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">url</span> <span class="o">:</span> <span class="s1">&#39;foo.php&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">dataType</span> <span class="o">:</span> <span class="s1">&#39;json&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">success</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">resp</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">debug</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">req</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;let&#39;s see that again!&quot;</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1">// return the request object so other</span>
</span><span class='line'>  <span class="c1">// things can bind to it too!</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">req</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doAjax</span><span class="p">().</span><span class="nx">success</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">){</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;Once more, with feeling!&quot;</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Starting with 1.5 (I&#8217;m guessing), users will be able to easily attach callbacks
to XHRs &#8230; later! And pass around the return value of <code>$.ajax</code> as an actually
useful object with a familiar API, rather than just getting back the native
XHR! No longer will we have to bundle up callback functionality &#8211; some of
which might be optional, or depend on other code &#8211; inside our success or error
callbacks. So hott.</p>

<p>When I heard that these Ajax changes had landed, I got to thinking about how
Dojo provides its ability to belatedly attach success and error handlers to its
XHRs: underlying its XHR methods is
<a href="http://dojotoolkit.org/reference-guide/dojo/Deferred.html#dojo-deferred">dojo.Deferred</a>.
It <strong>allows users to assign callback functions for success and error conditions
for a task that may not complete immediately.</strong> Dojo makes use of this for its
XHR stuff, but it&#8217;s incredibly useful generically, too:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">doSomethingAsync</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">dojo</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">();</span>
</span><span class='line'>  <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;hello world&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">5000</span><span class="p">);</span>
</span><span class='line'>  <span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">;</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doSomethingAsync</span><span class="p">().</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">resp</span><span class="p">);</span> <span class="c1">// logs &#39;hello world&#39;</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>So, Dojo provided the late callback functionality via deferreds. jQuery now had
late callback functionality. Was the deferred functionality hidden in the
jQuery Ajax rewrite, waiting to be exposed? Julian and I and several others got
to talking in the jQuery development IRC channel, and decided it seemed like an
interesting and viable idea. A few days later, Julian&#8217;s <a href="https://github.com/jquery/jquery/commit/116c82b027a03a7a5670fa580fa9af819cc1cc03">first draft of jQuery.Deferred</a>
landed in a branch on GitHub.</p>

<p>It&#8217;s early days, but there have been a lot of good discussions already about
the proposed API and how it should work. Through all of the conversations I&#8217;ve
been part of, it&#8217;s become really clear that no one cares about deferreds until
you show them what they actually mean: the ability to register an interest in
the outcome of arbitrary asynchronous behavior, <em>even if the outcome has
already occurred</em>. Even better, you can register your interest in the outcome
of behavior that <em>may or may not be asynchronous</em>.</p>

<p>I assure you that once you have experienced this, you will wonder how you lived
without it.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">cache</span> <span class="o">=</span> <span class="p">{};</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">doSomethingMaybeAsync</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="nx">cache</span><span class="p">[</span><span class="nx">val</span><span class="p">])</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">return</span> <span class="nx">cache</span><span class="p">[</span><span class="nx">val</span><span class="p">];</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">url</span> <span class="o">:</span> <span class="s1">&#39;foo.php&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">data</span> <span class="o">:</span> <span class="p">{</span> <span class="nx">value</span> <span class="o">:</span> <span class="nx">val</span> <span class="p">},</span>
</span><span class='line'>    <span class="nx">dataType</span> <span class="o">:</span> <span class="s1">&#39;json&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">success</span> <span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">cache</span><span class="p">[</span><span class="nx">val</span><span class="p">]</span> <span class="o">=</span> <span class="nx">resp</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">when</span><span class="p">(</span><span class="nx">doSomethingMaybeAsync</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">))</span>
</span><span class='line'>  <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">){</span>
</span><span class='line'>    <span class="nx">alert</span><span class="p">(</span><span class="s2">&quot;The value for foo is&quot;</span><span class="p">,</span> <span class="nx">resp</span><span class="p">);</span>
</span><span class='line'>  <span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>It&#8217;ll also be possible to do something like you see below. I&#8217;m not sure what
the exact API will be for creating a generic deferred instance, but I hope it
will be something along these lines:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">function</span> <span class="nx">doIt</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="kd">var</span> <span class="nx">dfd</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">$</span><span class="p">.</span><span class="nx">Deferred</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'>  <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">dfd</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="s1">&#39;hello world&#39;</span><span class="p">);</span>
</span><span class='line'>  <span class="p">},</span> <span class="mi">5000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">return</span> <span class="nx">dfd</span><span class="p">.</span><span class="nx">promise</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nx">doIt</span><span class="p">().</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">resp</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">resp</span><span class="p">);</span> <span class="p">},</span> <span class="nx">errorFn</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>These changes are sitting in a <a href="https://github.com/jquery/jquery/tree/deferred">branch in the jQuery GitHub repo</a> as we speak, and I think
it&#8217;s likely we&#8217;ll see them move to master sooner than later. It&#8217;s a nice story
of collaboration and community participation that helped make something good &#8211;
the Ajax rewrite &#8211; even better.</p>

<p>It&#8217;s exciting to see jQuery venture a bit more into the abstract. My
experiences with Dojo core so far make me think there are probably more
opportunities for these sorts of utilities that would be of high value for
a substantial number of jQuery users. On the other hand, one of the constant
themes of our conversations about deferreds has been the potential for
confusion with the new methods. Will the API look familiar and jQuery-like, or
will users be confused about the ability to chain methods on something other
than a jQuery selection? Are there bigger-picture considerations when it comes
to adding new constructors to the jQuery namespace? It&#8217;ll be interesting to see
how these questions sort themselves out, especially if other similar features
appear that don&#8217;t fall neatly under the well-established
DOM/Ajax/Events/Effects umbrella.</p>

<p>The <a href="https://github.com/jquery/jquery/commits/deferred">conversation&#8217;s happening on GitHub</a> &#8211; I hope you&#8217;ll
join in.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[On Conferencing]]></title>
    <link href="http://rmurphey.com/blog/2010/11/20/on-conferencing/"/>
    <updated>2010-11-20T00:00:00-05:00</updated>
    <id>http://rmurphey.com/blog/2010/11/20/on-conferencing</id>
    <content type="html"><![CDATA[<p>I&#8217;m a few hours away from finalizing my slides for the Rich Web Experience in Ft. Lauderdale next month. I&#8217;ll be presenting on basic tips for refactoring your jQuery; I think it&#8217;s a decent presentation &#8211; the part of it I&#8217;ve finished, anyway &#8211; and I&#8217;ll be glad to have it in my collection.</p>

<p>By my count, RWX will be the 15th conference or non-trivial event I attend in 2010, including two that I&#8217;ve organized and eight that I&#8217;ve spoken at:</p>

<h2>Organizer</h2>

<ul>
<li><a href="http://texasjavascript.com">TXJS</a> (Austin, TX)</li>
<li>NCJS (Durham, NC)</li>
</ul>


<h2>Speaker</h2>

<ul>
<li>JSConf EU (Berlin, Germany; &#8221;<a href="http://www.slideshare.net/rmurphey/the-jquery-divide-5287573">The jQuery Divide</a>&#8221;)</li>
<li>Boston jQuery Conference (Boston, MA; &#8221;<a href="http://www.slideshare.net/rmurphey/functionality-basedorg">Functionality Focused Code Organization</a>&#8221;)</li>
<li>jQuery Summit (Online; &#8221;<a href="http://www.slideshare.net/rmurphey/functionality-basedorg">Functionality Focused Code Organization</a>&#8221;)</li>
<li>Indieconf (Raleigh, NC; &#8221;<a href="http://www.slideshare.net/rmurphey/retooling-your-workflow">Retooling Your Workflow</a>&#8221;)</li>
<li>Refresh the Triangle (Durham, NC; &#8221;<a href="http://www.slideshare.net/rmurphey/delivering-a-responsive-ui">Delivering a Responsive UI</a>&#8221;)</li>
<li>Triangle JavaScript Meetup (Durham, NC; &#8221;<a href="http://www.slideshare.net/rmurphey/building-large-jquery-applications">Building Large jQuery Applications</a>&#8221;)</li>
<li>Rich Web Experience (Ft. Lauderdale, FL; &#8220;Cleaner, Leaner, Meaner: Refactoring Your jQuery&#8221;)</li>
<li>Durham Developer Day (Durham, NC; &#8221;<a href="http://www.slideshare.net/rmurphey/dojo-confessions">Dojo Confessions</a>&#8221;)</li>
</ul>


<h2>Attendee</h2>

<ul>
<li>SXSW (Austin, TX)</li>
<li>Bay Area jQuery Conference (Mountain View, CA)</li>
<li>JSConf US (Washington, DC)</li>
<li>CouchCamp (Walker Creek Ranch, CA)</li>
<li>Dojo Developer Days (Mountain View, CA)</li>
</ul>


<p>(For what it&#8217;s worth, and because I was curious enough to count: I&#8217;ve also participated in 11 episodes of <a href="http://yayquery.com">yayQuery</a>, written a half-dozen in-depth blog posts, organized at least six local web women meetups, and published an open <a href="http://jqfundamentals.com/book/book.html">jQuery training curriculum</a>.)</p>

<p>It was sometime in early 2009 that I decided to make a point of speaking at more events. I&#8217;d always enjoyed the challenge and the thrill of public speaking, but I also wanted to be part of the solution to the dearth of women speakers in JavaScript land. Something like 18 months later, it seems I might be sort of good at it, if my SpeakerRate is to be believed. This fall I found myself actually turning down requests to speak.</p>

<p>It turns out that they forgot to remind me in work-for-yourself school that at the end of the day or week or month, I&#8217;ve still gotta make some money now and then. Putting together presentations and traveling to conferences and meeting the expectations that come along with being a Vaguely Important Person &#8230; it&#8217;s fucking hard work, and when there&#8217;s no company to pay you for it, it&#8217;s also fucking expensive, even if it theoretically brings in work in the long run. While every non-local event I spoke at paid for my hotel and accommodations, I was not otherwise compensated. The events that I organized ended up being pretty much a wash, financially.</p>

<p>I spent untold hundreds of hours &#8211; I&#8217;m not making that up &#8211; preparing presentations, traveling to conferences, and speaking this year. Looking back at my calendar since late August, when all of this got really and truly insane (most of my speaking has happened since then), the sad size of my business bank account makes stunning sense. We&#8217;ll leave aside the toll that working all the time and then being gone all the rest of the time takes on one&#8217;s home life, but suffice to say that the toll is, also, not trivial.</p>

<p>Over the last few weeks, it&#8217;s become pretty clear that I need to take a break. I&#8217;m mostly over pre-talk jitters, but these days I find myself thinking &#8220;for the love of all that&#8217;s good, do I really have to get on a plane again?&#8221; People ask me about 2011 events and I find myself on the verge of losing my shit, which really isn&#8217;t fair to anyone. People tell me how they want to be invited to speak at stuff like I am, and I let loose a heavy sigh. People come up to me at events or email me randomly because they think that I&#8217;m an &#8220;expert&#8221; on this thing or that, and can they just ask me a little question? &#8211; and I wonder what, exactly, I have wrought with all of this effort. Worst of all: potential clients ask me about taking on lucrative work, and I must tell them: &#8220;Not now, I can&#8217;t, I&#8217;m sorry. I&#8217;ve got this presentation to prepare &#8230;&#8221;</p>

<p>I might be a terrible person entirely too full of herself, or a drama queen, or whatever else you want to think. You might be certain that if I&#8217;d just think about it, there would be lots of efficiencies I could realize, and really I just make this harder than it is. That&#8217;s OK, and you might be right.</p>

<p>I want to be clear that I realize that two years ago I was nobody, and to the extent that I am anybody now, it is largely because I have been afforded so many opportunities to make a name for myself. I am grateful for them. It becomes clear, though, that I&#8217;ve let the pendulum swing way too far.</p>

<p>And so as I sit here, about to finish off the last slides of the year, I fantasize about deleting Keynote from my computer. But I also find myself thinking how I&#8217;m deciding not to do this thing that I&#8217;m kind of good at because I simply can&#8217;t afford to, and it makes me sad. It kills me to think about missing out on that warm fuzzy it-was-all-worth-it moment when everyone claps at the end. And more than anything, I feel like walking away, for however long, means yet one less woman on stage in a field that is desperate for them, and that makes me saddest of all.</p>

<p>There is no point to this post, really, except for me to get some of my thoughts out of my head and for you to know where I&#8217;ve gone if you don&#8217;t see or hear from me as much. It is, alas, time for me to actually do some of that work that all this effort has brought in. We&#8217;ll see when I emerge &#8211; maybe I will feel rejuvenated in the new year, who knows! &#8211; and whenever that is, I hope to see you there.</p>
]]></content>
  </entry>
  
</feed>

