Speks for Node.js

January 03, 2010

It’s been a long time since I’ve been excited to write about a topic. It’s been even longer since I’ve been excited about JavaScript. In fact, I’ve spent most of my career despising JavaScript. It’s a real shame because JavaScript is a beautiful and expressive dynamic programming language. And it’s taking a lot of rehabilitation in order for me to say that. JavaScript owes its popularity and bad reputation to the Internet. Specifically, the bad reputation is directly related to poor browser implementations and the script-kiddies (myself included) who amassed large piles of unmaintainable code. But this is changing and JavaScript has a great community to thank for that.

Node.js is a good example of how things are changing for JavaScript. I spent the past month learning and using node and it’s been a lot of fun. I strongly urge you to read about node if you’re not already familiar with it … cue the Jeopardy music.

So, um yeah, Node is awesome. It’s given me an opportunity to sharpen my JavaScript skills and learn more about writing concurrent applications. Plus it’s all server-side; so there’s no DOM and no cross-browser BS to worry about. What’s not to like?

My first Node project of any significance is a testing framework. It’s a simple RSpec derivative for node-code cleverly titled Speks (I know, brilliant right?). Speks is only a spec runner and a DSL for specifying your code but I have plenty of ideas for future enhancements. The anatomy of a spec is basic. It consists of a describe block, at least one nested it block and optional beforeEach, afterEach blocks. Like so:

describe("Sephiroth", function () {

  var s = require('../spec/examples/sephiroth');

  beforeEach(function () {
    sephiroth = new s.Sephiroth();
  });

  it("should be named 'Sephiroth'", function () {
    sephiroth.getName().shouldEqual('Sephiroth');
  });
  
});

I’ve augmented some of the built-in JavaScript types to improve the readability of the specification code. The prototyping only occurs during the execution of a spec-run. There’s currently a dozen or so of these should prototype methods and I’ll be adding more soon. I’ve listed the available methods below.

// Object
obj1.shouldEqual(obj2);
obj1.shouldNotEqual(obj2);
obj1.shouldBeSame(obj1);
obj1.shouldNotBeSame(obj2);

// Boolean
true.shouldBeTrue();
false.shouldBeFalse();

// String
"foo".shouldMatch(/foo/);
"foo".shouldNotMatch(/bar/);

// Number
(1).shouldBeGreaterThan(0);
(2).shouldBeLessThan(1);

Download the source and try it for yourself; I could use the feedback.

Sign in, Login, Sessions

November 12, 2009

I started a new Rails project last week and had a lot of new-project questions to answer. On every new project, I try to get the boring tasks out of the way as early as possible. Getting a new project started fast is one of the advantages in using Rails but it’s inevitable that you’ll face some problems or decisions that require a pilot. And depending on how often you start new projects or how long it’s been since you started one, you’ve probably forgotten a thing or two. I know I did, but that’s why we have Google.

I began work on the sign in/sign up features since most of my stories require a user. I used authlogic for authentication because it’s awesome (pragmatic, I know). But I couldn’t decide between the phrase “login” or “sign in” so I hit the wild-web to do some research. My research (quick and unscientific) revealed an alarming amount of inconsistency. So I decided to go with “sign in” and move on with life.

While working on the sign in page I stumbled over another problem. If authentication failed, then my nice /signup route was replaced with the ugly /user_session route. So I hit the web again in search of a definitive answer. What I found this time was even more alarming than what I found the first time. There are numerous popular sites that have the same problem. Some sites had sign up links pointing to /login routes and others weren’t even from the same planet. I was unhappy with all the inconsistency. It’s the kind of mess I lose sleep over.

If you want to see for yourself, just have a look at twitter’s sign in page. Twitter’s link reads “login” and as you would expect, it takes you to the /login route. The header and button on the page read “Sign in” and “Sign In” respectively. If you fail to correctly enter your username or password you are redirected to the /sessions route. Whaaaa? I’m not trying to pick on twitter; they weren’t the only offenders. Take a look at github or justin.tv or peepcode’s website. That’s just a small sampling.

I solved my issue with a simple change to the routes.rb file and a small tweak to my sign in form. I updated my sign in form to post to the signin_path and added the following lines to routes.rb:

map.signin 'signin', :controller => 'user_sessions', 
:action => 'new', :conditions => { :method => :get }

map.signin 'signin', :controller => 'user_sessions', 
:action => 'create', :conditions => { :method => :post }

Introducing MacVim

October 11, 2009

I hate VI. Well, I used to hate VI. Back in my Sys. Admin. days, I avoided VI like I owed it money. I was convinced my *nix savvy coworkers were hittin’ the pipe. They couldn’t persuade me with banter, intelligent conversation or free beer (yep, even free beer). I was a Windows guy; a right click wonder. In the age of GUIs, rodent peripherals and boy bands, why would I waste time cramming archaic commands into to an already overcrowded brain? Every time I encountered VI, I asked myself the same question. “How the hell does anyone use this sh*t?”

Sadly, I didn’t leave my comfort zone long enough to answer that question. I wasted years avoiding VI due to an irrational aversion to learning (the kind of behavior I so deeply despise). If you’re going to say nay to a tool, then you should be able to intelligently articulate the reason(s) why. That wasn’t the case with VI.

In an effort to change that, I installed MacVim. The first few minutes were intimidating but rather than run in terror, I took to Google. After skimming a few blog posts and tinkering with config files on GitHub, the intimidation was no more. My nerd-sense was tingling. It was clear I wasn’t dealing with the crusty command line VI that ate noobs for breakfast. Nope, MacVim was noob friendly. Several hours and a few commands later, I was easily moving though my code. Thanks to plugins, I was able to extend MacVim with most of the features that make TextMate such an amazing editor. I was also pleased that it looked like a mac app and not some hideous Linux port.

Conclusion

It’s to early to corroborate the stories of enhanced productivity but in the meantime, I’m having fun. I know vim’s not for everyone and you don’t have to drink the kool-aid. I simply wanted to share an experience and maybe inspire an open-mind. Besides, learning new things is good to fend off zee stasis.

My current MacVim configuration is on GitHub if you’re so inclined.

Labor Day Special

September 07, 2009

I’ve been writing a lot about development lately and I’ve finished zero illustrations. Unless you count my 404 page, but I don’t. The last seven posts are all programming related. Today the streak ends! That’s correct, today I spit in the face of technical posts and give you something from the other side of my brain. A new illustration; the perfect monotony breaker. Besides, I don’t want anyone getting the idea my talent is one dimensional ;)

Metal Hand

Certainty Is Fleeting

August 23, 2009

In the land of software development, certainty has a short life and often dies a painful death. Guarantees are beasts of myth and getting it right the first time is as unlikely as you slaying a fire-breathing dragon. Today’s solution maybe tomorrow’s problem and architecture that provides no real business value is the dark overlord.

You’re probably thinking one of two things, “what the hell is he talking about?” or “You’re so right, now what?” Well if you’re one of the “now what?” people, all is not lost. Knowing what makes this land so unpredictable will help. There are three key reasons for this unpredictability:

  1. Today's problem isn't necessarily tomorrow's problem.
  2. We will know more tomorrow than we know today (duh).
  3. The landscape is changing (languages, tools, and techniques are evolving).

The problems listed above have a lot in common and so do their solutions. How can you be certain when everything is changing? Don’t try to solve tomorrow’s problem today. Just focus on the problem at hand. A simple solution is easy to change (or easier to change than its complex counterpart). I’m sure your experience is telling you, you need to future-proof your application so it’s robust and scalable. Perhaps, I’m not saying that’s impossible. But let’s be honest with our selves, tomorrow doesn’t exist and its problems may never materialize. So unless someone is paying you to create an elaborate architecture or you have droves of users, your application may never need to scale. Especially if it’s a steaming pile of bad-user-experience.

Number two should be obvious, hence the “duh.” This point is best embellished by my favorite quote from Men in Black:

"A person is smart. People are dumb, panicky dangerous animals and you know it. Fifteen hundred years ago everybody knew the Earth was the center of the universe. Five hundred years ago, everybody knew the Earth was flat, and fifteen minutes ago, you knew that humans were alone on this planet. Imagine what you'll know tomorrow."

Reason number two doesn’t stand alone. Two and three have a symbiotic relationship. Software development is not a static discipline. You must be able and willing to adapt. Change is inevitable and accepting that fact will make it easier to deal with. So how should you spend your effort? Focus your effort on learning as a general practice; discover how you learn. Your ability to learn (and unlearn) is your most valuable skill. It’s good to keep-up with the new stuff all the cool kids are doing but that shouldn’t be your only concern. Attachment to techniques, vendors or tools will only hinder your learning. Having the ability to shed your scaly skills and grow new skills is a great virtue. You should be objective when evaluating a new technique, vendor or tool. Not because I said so, but because preference tends to cloud our ability to recognize merit.

Becoming a good software developer is a journey. Don’t get too high and don’t get too low. Avoid getting caught up in the coolness of your shiny new code. Give yourself a small pat on the back and move on. If you find out later that the code wasn’t all that special or maybe a bit buggy, don’t worry. This is a pretty regular happening. Keep your decisions and your designs small. Large complex systems are composed of many simple working parts. If you’re writing code for a complex system, ensure the pieces you’re responsible for are simple and work well. The future is uncertain and your code should mirror that reality

Dispassionately Discussing Software Development

August 09, 2009

Talking shop with other developers is an essential part of learning and growing your skills. These discussions should be enjoyable and full of reminders why you love programming. But to often the opposite is true. All it takes is one lout who had a little too much passion fruit for breakfast to dissolve an intelligent conversation into an awkward emotional mess. I’ve been guilty of and victimized by this brand of impetuous passion. Developers are notorious for this type of behavior. There’s nothing essentially wrong with being a passionate software developer; it’s more how you choose to wield this blunt instrument. Passion, in fact, is a requirement to sustaining a long and successful career as a software developer. But when your passion evolves into zealotry or dogmatism it becomes a burden. Earning the reputation of zealot, becomes an obstruction to learning and teaching.

Credibility is essential to having your ideas and teachings accepted by your peers. Achieving credibility can be difficult but maintaining it doesn’t have to be. A sure fire way to lose credibility is constantly giving into your compulsion to share how cool you or your latest bit of code are. Another way, without doubt, is discussing your craft in an irrational or emotional manner. If your credibility is damaged, your contributions to a discussion will often be tuned out or met with hostility. If you’re the type of person who loves the sound of your own voice, you probably have no idea when you’re being tuned out. The problem should be easier to diagnose if you’re constantly involved in heated or emotional exchanges.

On the other hand, If you have a reputation for being abrasive or narrow minded, you could be limiting your exposure to new topics. Your peers may be reluctant to share new ideas with you. At the extreme, they may avoid discussions with you entirely. So how can you avoid this sentence to Mars?

A developer needs to check their passion (at all times). Assume you have something to learn and be respectful. Don’t waste the precious time of others with mindless chatter; if you have nothing of value to contribute, don’t. Superstition, fear and attachment aren’t valid arguments in any conversation and they should be avoided. Overreacting is an evident presage that you’re losing control. If you lose control of your passion, it can quickly run amok. Your vision and judgment are immediately compromised and your input going forward is questionable.

When a discussion reaches this point, the time and effort allotted to the discussion can be tracked as waste. Being able to identify when your discussion has reached the point of waste is critical. If you’ve stopped listening, stopped participating, are consumed with defending your point of view or you’ve reached the limits of your knowledge and experience, then the value of the discussion is sharply diminishing. It should be quickly concluded or aborted. More obvious signs include flares of temper, shouting or decreasing professionalism. You should also be observing the other participants to see if they’re exhibiting any of these signs. There is no point in continuing if all parties aren’t receiving equal value.

The exchanging of ideas with others should be pragmatic and thoughtful. Calling this exchange a discussion is a misnomer. They should be conducted as a dialogue. These dialogues should be focused around growth and improvement. All techniques and practices should be candidates for evaluation. We must remain in control of our passion and exile it from conversation. If you can learn to discuss software dispassionately, all the knowledge are belong to you.

RSpec and Sinatra Quick Start

August 01, 2009

Are you familiar with RSpec, new to Sinatra, and can’t get the two to cooperate? This article maybe of use to you. Alternatively, if you’re like me and you’re simply new to this universe all together, this article can certainly be of use.

I recently started playing with learning Sinatra after months of procrastination. I started with some exploratory (throw away) code. My preliminary results were good and I was quickly hooked. I needed a more substantial problem to solve. I decided to take this site and redo it using Sinatra. The first task I needed to tackle, was learning how to specify my Sinatra application. I prefer RSpec, so naturally I focused my effort on getting RSpec setup with Sinatra. After running through this setup a few times, it seems like trivial knowledge to share. At the time, it took some real investigation to get it all going. If I can save (at least) one person a little time, then this article has served a purpose. As a bonus, if you’re using autospec, the following setup is compatible.

I’ll assume you’ve used RSpec before and you’re machine is configured correctly. If this assumption is incorrect, you can get up to speed here.

As a prerequisite, we need to add a few things to your filesystem. Here’s the list:

  1. Make a new spec folder in the root of your application folder
  2. Make a new spec_helper.rb file inside your spec folder
  3. Make a new spec.opts file inside your spec folder
  4. Make a new spec file inside your spec folder for your application
    ex. myapp_spec.rb

If you’re down with some terminal action, you can use these commands to accomplish all the steps above.

$ cd your/app_dir/
$ mkdir spec
$ touch spec/spec_helper.rb
$ touch spec/spec.opts
$ touch spec/myapp_spec.rb

Spec Helper

Lets move on to the spec_helper setup, shall we? The setup is pretty simple and for the most part, you can just paste in the following code and you’ll be good. There is one thing to note. Sinatra now relies on Rack::Test and has deprecated the use of Sinatra::Test.

Update: Vinicius has pointed out a few oversights in this article. The first is myapp.rb found on line one of the spec_helper. If the file that contains your application isn’t named myapp.rb (and it probably isn’t), you should update myapp.rb to match the name of your application file. Before continuing, you also need the rack-test gem installed. Simply issue the “sudo gem install rack-test” command at the command-line and you’ll be ready to proceed.

require File.join(File.dirname(__FILE__), '..', 'myapp.rb')

require 'rubygems'
require 'sinatra'
require 'rack/test'
require 'spec'
require 'spec/autorun'
require 'spec/interop/test'

# set test environment
set :environment, :test
set :run, false
set :raise_errors, true
set :logging, false

The spec.opts file is even simpler to setup. These are the basic options I use.

--colour
--format progress
--loadby mtime
--reverse

The Spec File

Now that all the setup work is complete we can write some specs. Requiring our spec_helper.rb file will grant our spec the magical powers it needs to be useful. The last thing we’ll need to do is include Rack::Test::Methods. We get all the goodies of Rack::Test via a mixin and we don’t need to inherit from a super class (I’m really happy they did it this way). The basic template for your specs will look like this:

require File.dirname(__FILE__) + '/spec_helper'

describe "My App" do
  include Rack::Test::Methods

  def app
    @app ||= Sinatra::Application
  end

  it "should respond to /" do
    get '/'
    last_response.should be_ok
  end
end

You can use last_response for most of your testing needs. You can test response headers like so:

it "should return the correct content-type when viewing root" do
  get '/'
  last_response.headers["Content-Type"].should == "text/html"
end

Testing status:

it "should return 404 when page cannot be found" do
  get '/404'
  last_response.status.should == 404
end

Testing the output:

it "should return blah blah blah when viewing root" do
  get '/'
  last_response.body == "blah blah blah"
end

That wasn’t that bad, was it? It would be a tragedy if the beautiful simplicity of Sinatra was paired with a complicated testing experience. That said, I think RSpec and Sinatra make great crime partners. If you’ve made it this far, let me reward you with a few more things you should probably read: Rack::Test Documentation, Testing Sinatra with Rack::Test. You can also explore the source for this site’s specification.

How to Copy Folders Recursively With Ruby

July 28, 2009

Ruby, out of the box, provides many useful classes for working with files and directories. Most of these handy-dandy methods can be found on the FileUtils class. Ruby even makes it easy to copy directories recursively. Since recursive directory copying is the topic of the day, I thought I’d burn a few lines talking about just that. The FileUtils.cp_r method is a fine way to copy directories recursively. It works exactly as advertised.

The FileUtils class, IMHO, has a missing a method. It’s a method very similar in behavior to cp_r, that accepts a list of files to ignore/exclude recursively. If for some wacky reason you also have a need for this behavior, then you’re in luck.

Below you’ll find a tiny script that allows you to do just that. You can initialize the object with an array of files or patterns to exclude, then invoke the solitary copy method. That’s all there is to it. The script will recursively copy the source directory to the destination directory and compare each file against your exclude list.

require 'FileUtils'

class DaCopier

  def initialize(exclude)
    @exclude = exclude
  end

  def copy src, dest

    stage dest

    Dir.foreach(src) do |file|
      next if exclude?(file)

      s = File.join(src, file)
      d = File.join(dest, file)

      if File.directory?(s)
        FileUtils.mkdir(d)
        copy s, d
      else
        FileUtils.cp(s, d)
      end

      puts d

    end
  end

  private

  def stage dest
    if File.directory?(dest)
      FileUtils.rm_rf(dest)
    end

    FileUtils.mkdir(dest)
  end

  def exclude? file
    @exclude.each do |s|
      if file.match(/#{s}/i)
        return true
      end
    end
    false
  end
end

src = '/Users/Emilio/Dropbox'
dest = '/Users/Emilio/Dropbox 2'
exclude = ["^\\.", "_old", "cheese.jpg"]

dc = DaCopier.new(exclude)

dc.copy src, dest

DISCLAIMER: This script is not battle tested and you’ll probably want to run it through your own tests before using it in any production scenario.

One Heroku App From Two Computers

July 18, 2009

First, let me start by giving you some context. I own two macs and they each have distinct responsibilities. I do most of my development on my macbook and I use my iMac for graphics. Earlier this morning, I was working on a custom 404 page for this site. This required some Illustrator work and of course my iMac. When the design work was finished I realized that the git repository for this site was on my macbook. I wanted to avoid switching computers. I thought, no problem, I’ll just clone my repository from github and I’ll be ready to rock. It was that simple, until I reached the deploy step.

Time to Deploy

Deploying a Heroku app is dirt simple. Heroku host a great doc that demos how simple it is and I can’t say enough about Heroku’s awesomeness. While working this morning, I hit the documentation looking for information on how to setup my second computer. I couldn’t find anything on the topic. At least not in my particular context. My inability to resolve this issue rapidly was a result of my inexperience with git and not a problem with the Heroku documentation. In hindsight, I could’ve resolved this issue using the Heroku documentation exclusively.

All of the Heroku examples show you how to start an application from scratch using heroku create. Since I was working with an existing application, I couldn’t use create. At the time I was thinking I needed to tell heroku “locally” the app name for the repository I was working with. Instead, I had to tell git how to push to heroku.

The Solution

At this point, you should already have the Heroku gem installed. If so, you can be up and running with these four simple commands.

$ git clone git://github.com/youraccunt/appname.git
$ heroku config
$ git remote add heroku git@heroku.com:appname.git
$ git push heroku master

Conclusion

The magic is really line number three. This is something you need to do on a per repository basis. While working in the context of your repository, you can type the command git remote to see a list of already configured hosts.

This is Farewell

July 07, 2009

I’m declaring my intention to migrate my blog away from WordPress (ironically using WordPress). WordPress is fantastic application, probably one of the best PHP applications I’ve ever used. It’s only flaw, according to me, is the applications abundance of features. I only use a small subset of it’s features and don’t have any real requirements for an HTML abstraction (because I’m all web savvy and stuff). Being a fan of simplicity, I’m always seeking ways to reduce complexity. This blog is no exception.

In case you’re wondering, I’ll be migrating my blog to a Sinatra based solution. The event that lead me to make this decision occurred accidentally. I was just minding my own business, doing a little Sinatra research when I stumbled upon an amazing blog solution. I found it while reading Enter Sinatra on http://hughevans.net/. I realized after a few minutes of inspecting the project on GitHub, that the code was an excellent example of the simplicity I covet. I also took a minute to look over the toolmantim project that inspired Hugh Evans. If you’re interested in Sinatra, I suggest you take a look at both projects.

Hopefully the next time you hear from me I’ll be speaking to you all from atop a Sinatra platform.

View First

July 05, 2009

I’ve been working on an experimental side project using Rails. The project details aren’t important since today’s subject is generally applicable to software development. I started my project by specifying a few domain objects. Two objects to be precise. This is the typical way that I work–it’s very DB centric. While working, I noticed that I was doing a lot of guess work. My user stories and UI sketches were gently hinting that the model wasn’t the logical next step. After a brief pause, I decided that this experimental project was the perfect opportunity for an experiment.

I switched focus, and fired up the HTML/CSS machine. As difficult as it was, I put a freeze on writing any new code. I found it refreshingly easy to translate user stories into views; my progress was natural and effortless. The resolution of a user story is adjacent to that of a view. Both view and user story are centered around how a user should interact with an application. Working on the view undoubtedly shortened the feedback loop that’s critical to an Agile development process. I wasn’t creating any behavioral code but I was developing very real HTMl and CSS. I wasted no time guessing about database fields or needless architecture.

When I was finished, I had views that visually represented my user stories. Starting with the view first eliminated waste that I would’ve normally accumulated at this point in a project. I was able to evolve requirements quickly without throwing away globs code. To further illustrate my point, the simple domain objects (and corresponding tables) I started with required modifications to remain inline with my evolving application.

The only thing left for me to do now, is test and code the behavior required by my views.