My Review of Node for Front-End Developers
Or... Prototyping with Node.js
Pros: Well-written, Easy to understand, Concise, Accurate, Helpful examples
Cons: Too short
Best Uses: Student, Novice
Describe Yourself: Software Engineer
I've reviewed "Node for Front-End Developers" for the O'Reilly blogger program. Because I've been contributing to an open-source Node.js ebook, I was very excited to read this book. I must warn you-- this book is less about Node.js than it is about prototyping web applications using modules available in Node.js. If you begin reading this from that perspective and you have little knowledge of Node.js in general, you will gain a lot from reading this. If, however, you have experience with Node.js and have used frameworks such as Express and Connect, there is not much more covered in these 58 pages.
Garann Means has written this book in a great way. She doesn't start off explaining the Express framework like most introductions to Node.js would have done. Instead, she shows how to create a minimal http server, add templating and middleware, and then discusses Express and separating concerns into an MVC or MVC-like pattern.
There are a few times where I think the terminology could be misleading. For example, at the beginning she talks about 'scaffolding'. Scaffolding in general implies code generation and the only bit of true scaffolding discussed in the book occurs on one line in one of the last few chapters when the Express framework generates an empty application. I would have liked to see some true 'scaffolding' examples, either with code specific to the book or with third-party modules. Aside from one or two other terminology issues (which is probably just me being picky), the content is spot-on.
Garann does talk about asynchronous operations a little, but this is a huge area of concern for front-end and back-end developers when migrating to Node.js because the asynchronous and event-driven nature of common tasks (files, database) can often increase the complexity of a simple task. Had she expanded on the asynchronous nature of Node.js more, I would have given this book five stars. She does offer a caveat in the Postscript that this book doesn't cover all there is to know about Node.js, and she's right. Before or after reading this, you should read the introduction in the Node.js documentation and the Express framework's documentation.
In conclusion, this is an excellent introduction to prototyping web applications using Node.js. I would recommend this book to people who are familiar with JavaScript programming and want to being prototyping without the need to learn additional languages and frameworks like Ruby on Rails, Catalyst, ASP.NET MVC, etc.
(legalese)
My Review of McCullough and Berglund on Mastering Advanced Git
Great demonstration of advanced Git
Pros: Accurate, Easy to understand, Concise, Helpful examples
Best Uses: Novice, Student, Expert, Intermediate
Describe Yourself: Sys Admin, Maker, Developer, Educator, Designer
At just under 4 hours long, this video course packs in a lot of content. Each video is about 30 minutes long, so I didn't have to watch it all in one sitting.
The structure of the demonstration is extremely useful because Tim and Matthew ask and answer questions conversationally while showing a split-view Git workspace. I think the hardest thing for some people to grasp in general about git is what 'distributed' means. Although the presenters are working from the same machine, the setup is done in a way to demonstrate this distributed nature.
I've been using git for a while, but I have learned a lot from these videos. I've only somewhat dug into the files inside the .git directory on my own because I was afraid to 'ruin' my repository. This course does a great job of alleviating a lot of those concerns by explaining the organizational structure of the .git contents.
If you're like me, you'll probably add quite a few of the concepts you learn from these videos to your repositories immediately after each video.
(legalese)
Mastering Node: Addons and FunctionTemplate (uuid.node)
Last night, I pushed an addition to my fork of Mastering Node. I decided to add a bit to the Addons chapter. The first example in this chapter only shows how to add a function to a natively-compiled module (i.e. an addon). This example shows you how to start a module which can be used in the following way:
var Uuid = require('./uuid.node').Uuid;
var uuid = new Uuid();
var myId = uuid.generate();
The project files referenced in the following text can be downloaded from the repo: jimschubert/masteringnode
FunctionTemplate
In v8, a FunctionTemplate is used to create the equivalent to:
var template = function() { }
The function at this point is an object and not an instance of the function.
As an example, we will use the linux package uuid to generate a uuid. We will define the header for this addon as:
words.pl: slogan word generator
About a year ago, I was really into playing this game online where you were given a single sentence and you had to use the letters in that sentence to make up as many words as possible. The longer the word, the higher the points.
Creating a script may be considered cheating if you're in it for money. If you're in it for fun, script away. That's what I always say.
Here's the gist of it:
#!/usr/bin/env perl
# words.pl: Find all possible slogan words from a single sentence.
use strict; $|++;
@ARGV == 2 or die "usage: $0 input_file output_file 'sentence'\n";
my ($infile, $outfile, $sentence) = @ARGV;
$sentence = $sentence || 'how much wood could a woodchuck chuck';
open INPUT, "< $infile" or die $!;
open OUTPUT, "> $outfile" or die $!;
my $stdout = select STDOUT;
$| = 1;
select $stdout;
my %sentence_letters;
my $stmp = $sentence;
$sentence_letters{$&}++ while($stmp =~ s/[a-z]//);
print "Using the sentence '$sentence'\n";
print "Found the following letters:\n";
print "\t$_ - ". $sentence_letters{$_} ."\n" foreach(sort(keys %sentence_letters));
print "Processing $infile for slogan words\n";
my $count = 0;
my @indicators = qw{\ / | .};
LINE: while(<INPUT>) {
my $word = $_;
my $tmp = $word;
next LINE if($word =~ /['\&\d]/);
my %word_letters;
$word_letters{$&}++ while($tmp =~ s/[a-z]//);
foreach(keys %word_letters) {
next LINE if ($word_letters{$_} > $sentence_letters{$_});
}
print OUTPUT $word;
my $word_len = length($word);
open WORD_LEN_OUTPUT, ">> $outfile.$word_len";
print WORD_LEN_OUTPUT $word;
print $indicators[++$count % 4], "\r";
}
print "\nDone.\nView $outfile.* for words\n";
When I wrote this, I had only recently started using Perl. Please go easy on me if it's poorly written.
The script takes an input file, an output file format (e.g. words.txt will be words.txt.20 for words of 20 characters), and an optional sentence to parse.
It gets a set of letters in the sentence, then runs through the list of words to see if the word can be made from any combination of letters.
For instance, if your 'sentence' is "baby cakes", the script will create a hash of those letters and their counts. Conceptually, this looks like:
// hash is an array hash['a'] = 2 hash['b'] = 2 hash['c'] = 1 hash['e'] = 1 hash['k'] = 1 hash['s'] = 1 hash['y'] = 1
If, while walking line-by-line through your list of words, the script sees 'abracadabra', the loop will return false because (conceptually):
word['a'] = 5 word['a'] <= hash['a'] == false
The script also employs some interesting stdout manipulation. This allows the script to output "spinner text" and update the current line when the terminating character is a line-feed.
To run the script in a linux-based environment, you may do:
mkdir ~/projects && cd ~/projects git clone git://gist.github.com/1733871.git gist-1733871 cd gist-gist-1733871 perl words.pl /usr/share/dict/words generated.txt 'Good goly, Miss Molly'
You should see output similar to:
jim at schubert in ~/projects/gist-1733871 on master* $ tree . . ├── generated.txt ├── generated.txt.1 ├── generated.txt.2 ├── generated.txt.3 ├── generated.txt.4 ├── generated.txt.5 ├── generated.txt.6 ├── generated.txt.7 ├── generated.txt.8 └── words.pl 0 directories, 10 files
If you look at generated.txt.7, you will probably see something similar to:
Hollis Osgood glossy goodly idylls igloos solids
My Review of Android Open Conference 2011: Complete Video Compilation
Hours of Android enjoyment
Pros: Helpful examples, Easy to understand, Accurate, Concise
Best Uses: Intermediate, Student, Expert
Describe Yourself: Developer
There are a lot of videos here. If you're only planning to write apps for the market, you'll most likely not be interested in the Embedded Android talk or Scala as a Java replacement. If you don't work on iOS and never plan to, you can probably scan through Nick Farina's talk (sorry, Nick). I found many of the videos worthwhile, whether they related to actual app development or the business of apps.
I also really enjoyed the keynotes. Tim O'Reilly's talk is probably my favorite because I've been saying the same things about many of Tim's comparisons since I bought my first DROID a couple of years ago.
Even if you're familiar with Android development, you should definitely watch the videos by Ken Jones. He shows the start of a Twitter client. Although he didn't get very far in the actual coding, he will point you to the finished code. One aspect I loved about his talks is that he discusses a lot of best practices. Many tutorials you find online either don't discuss best practices or don't incorporate them.
Be sure to watch the Arduino videos. I hadn't heard about Arduino before this video and I was very impressed. In fact, I watched the keynote video twice.
Honestly, there are some videos here that I'm not that interested in. That doesn't detract from the overall usefulness of this video collection. If you're 25% of the way through a video and it hasn't hooked you yet, move onto the next because there is a plethora of information.
(legalese)
dotfiles backup using GitHub
I was recently looking for a solution to backup my configuration files (bash, vim, etc) using GitHub. After some looking around, I've compiled a pretty nice project for myself.
First, this script checks dependencies. My dependencies are git, ruby, vim, tree, rake, gem, bundle, and trash. You could check out the code and add any number of dependencies here. Rubygems and bundler are required because the script later installs all gems listed in Gemfile.
Next, the script copies ~/.bashrc to ~/.bashrc.local. This allows you to keep your current bash configuration as a 'local-only' config that doesn't get copied or committed to github.
The script, as I copied most of bootstrap.sh and the rakefile from @gf3, expects the repository to be cloned to ~/.dotfiles. From there, it calls rake.
Rake looks at every file in ~/.dotfiles and copies the corresponding file relatively from ~/ to, essentially, ~/dotfiles-backup/`date`. I recommend first running the backup to make sure your files are properly backed up.
rake backup
The script then calls 'bundle install' to install all gems. It then copies all files from ~/.dotfiles to replace those relative files that were previously backed up from ~/.
The post-install displays a message to remind you to edit .gitconfig and .hgrc.
Because I've done some copying and compiling, these are relative close to the three projects in the README for right now.
Here is an excerpt from the README:
Bash
$ tree ~/.bash
/home/jim/.bash
├── aliases
├── completions
├── completion_scripts
│ └── git_completion
├── config
├── functions
├── paths
└── prompt
The above files are loaded by .bashrc. The files are pretty self-explanatory, other than prompt which colorizes the bash prompt with tweaks for git.
Cool Aliases
- cd : pushd
- bd : popd
- cd.. | .. : back one directory
- cd... | ... : back two directories
- ^ up to five directories
- rm : trash
- undopush
- ip
- GET | HEAD | POST | PUT | DELETE | TRACE | OPTIONS
Config
- sets editor to vim
- sets English/UTF-8
- sets manpager
- sets commands to ignore in history
- sets noclobber (e.g. prevents
cat > IMPORTANT_FILEmistakes ) - sets nocaseglob (e.g.
ls ~/.B*will list contents of~/.bash)
Functions
The two functions, md and c may not seem like much, but they simplify some commands. For example:
$ md projects; git clone git@github.com:jimschubert/dotfiles.git && cd dotfiles
In the above line, md will create the projects directory and cd into it.
c stands for 'code' and works like this:
jim at computer in ~
$ pwd
/home/jim
jim at computer in ~
$ c dotfiles
~/projects/dotfiles ~
jim at computer in ~/projects/dotfiles on master
$
You can change it to whatever shortcut and issue reload, which is also an alias from this setup.
Screenshot
Notice the color scheme and github branch notifications created by ~/.bash/prompt.
Install nodejs under ChromeOS (CR-48)
Why would I want to do this?
I'm a software developer. I love javascript. I love node.js. I love the direction Google is taking web development, user interaction, and the web in general. Installing node.js opens up a lot of possibilities for me on my CR-48. I don't know if this will work on anything other than the CR-48, considering the machine has to be in developer mode for these instructions.
If you don't have a chromebook yet, or you don't know what they are... where have you been? But seriously, visit http://www.google.com/chromebook/ and check them out.
Before I start, let me first say that following these instructions may void your warranty if you have one, open your machine up to vulnerabilities, or replace existing files and cause instability. If you don't know how to revert or fix any issues that may occur, don't continue. I offer no sort of warranty, support, or anything else. Consider this a 'hack' of sorts.
I found a blog post detailing how to install an archive package and ruby on rails in ChromeOS. I followed part of these instructions and I have modified them to fit my needs.
Prerequisites
- You must have a Chromebook, possibly only the CR-48
- You must be in 'developer mode'
- You must have a writable rootfs (see above link for developer mode)
Instructions
Downloading and installing xz
- Download the xz package
- Enter crosh or VT-2 (CTRL+ALT+T or CTRL+ALT+→)
- If VT-2, login to the shell
- Run on the terminal: cd /home/chronos/user/Downloads
- Run on the terminal: tar -zxf xz-*.tar.gz
- Run on the terminal: cd usr
- Run on the terminal: cp * /usr/
Now that xz is installed in /usr/bin (verify by running on the command line: which xz), you will be able to extract certain files that are necessary for nodejs and possibly any other package you'd like.
Download and install nodejs and openssl.
The site claims openssl is optional, but node wouldn't open without it
- Download nodejs
- Download openssl
- Enter the terminal again and navigate to /home/chronos/user/Downloads
- Run on the terminal: xz -d node*.xz
- Run on the terminal: tar -zxfv openssl*.tar.gz
- Run on the terminal: cd usr
- Run on the terminal: cp * /usr/
Now you should have a working install of nodejs. You can use npm, for instance, to install express and jade.

Visual Studio and Interface property stubs
Last year, I posted a question on StackOverflow asking if it was possible to replace the property stubs for interface refactoring
Is it possible to change the stub used to implement interfaces in Visual Studio 2008?
For instance, when I choose either
Implement interface 'IMyInterface'
or
Explicitly implement interface 'IMyInterface'
Instead of a number of properties that look like this:
public string Comment
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
I'd like my properties to use the C# 3.0 auto-implemented properties and look like this:
public string Comment {get;set;}
I want to do this to avoid forcing this interface to be an abstract class.
I've looked through the snippets in the Visual Studio folder, but I didn't see any that would be appropriate. I've also googled and searched SO, and found nothing.
If this isn't possible, does anyone have a macro I can steal?
Thanks.
I then discovered that you can edit the file at:
[program files]\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Refactoring\PropertyStub.snippet
and modify the xml node 'Code' to contain the following:
<Code Language="csharp">
<![CDATA[ $signature$ { $GetterAccessibility$ get; $SetterAccessibility$ set;} $end$]]>
</Code>
I really wish this was the default for .NET 3.0 and higher (since auto-implemented properties have been around).
My Review of JavaScript: The Definitive Guide, 6th Edition
A tome of knowledge
Pros: Well-written, Accurate, Concise, Easy to understand
Cons: Huge
Best Uses: Student, Expert, Novice, Intermediate
Describe Yourself: Developer
This is an unbelievably thorough JavaScript book. It's definitely more of a reference book than a front-to-back read.
The first 12 chapters are an excellent introduction into the history of JavaScript and the core functionality of the language. There is a lot of information in these chapters that really shouldn't be overlooked-- especially Chapter 8: "Functions".
I especially appreciate the structure and the approach of the client-side section of the book. Flanagan makes it a point to avoid pushing JavaScript frameworks by explaining the features of the language first, followed by an explanation of the cross-browser simplification of using jQuery.
Later chapters cover additions to more recent browsers like client storage and HTML5 features. Those chapters unfortunately go by really fast. They're definitely not as in-depth as the JavaScript history part of the book.
The last two parts of the book are purely reference. This is pretty helpful, but it makes the book a lot thicker than most "guide" references.
I do agree with others that this book could use a few more examples, especially near the end when discussing JavaScript usage with new HTML5 APIs. If you're looking for an in-depth understanding of the core functionality of JavaScript, this is the book. It has helped me in numerous job interviews!
(legalese)
jQuery plugin: fixed table header
Here's a plugin that I wrote a while ago for fixing a table's header row on scroll.
This code is also available as a gist. Fork it and contribute.
(function($) {
$.fn.fixedHeader = function(options) {
var settings = {
selector: 'thead:first',
cssClass: 'fixed',
fixTo: 0
};
var _fixHeader = function(obj) {
var header = $(obj.selector, obj.elem);
if(header) {
var parent = header.parents('table:first') || header.parent();
(parent && parent.css({ borderCollapse: 'collapse'}) );
var data = header.data('fixedHeader') || header.data('fixedHeader', {
top: header.offset().top,
width: parent.find('tr:eq(1)').width(),
cells: parent.find('tr:eq(1) > td'),
processed: false
});
var top = data.top - $(document).scrollTop();
if( top < 0 ) {
header.addClass(obj.css);
if(!data.processed){
header.width(data.width);
for(var i = 0; i<data.cells.length;i++) {
$('th:eq('+i+')', header).width($(data.cells[i]).width());
}
}
} else {
header.removeClass(obj.css);
}
}
};
return this.each(function() {
var self = this;
if("object" === typeof options) {
$.extend(settings, options);
}
if($(self).parents('table:first')){
$(window).bind('scroll.fixedHeader', function() {
_fixHeader({
elem: self,
selector: settings.selector,
css: settings.cssClass,
top: settings.fixTo
});
});
}
});
};
})(jQuery);
A demo:

