hintme

I use jshint to lint JavaScript code in my projects. Typically I include a project-wide .jshintrc file which contains a set of the linting options I wish to be applied whenever jshint scans my code. I keep a gist with a list of all possible options and the settings I normally use. This works pretty well but I thought it might be nice to create a tool that would interactively prompt a user for jshint settings and then create a .jshintrc file based on user response. So I created hintme, a small node.js CLI tool that does just that.

hintme

Right now it iterates through every jshint option and prompts the user for a setting value. Each setting has a default value, which may be chosen by simply hitting enter at the prompt. Defaults were chosen based on a simplistic criteria, one which I tend to refine a bit:

  1. the default for enforcing options is always TRUE
  2. the default for relaxing options is always FALSE
  3. the default for environment options is always FALSE

I also want to add some better command arguments, such as being able to specify known settings via a switch (e.g.: –use=eqeqeq=true;forin=true). The user wouldn’t be prompted for these settings since they’ve been specified already.

The –live=true switch forces hintme to screen-scrape the jshint options page and then prompt the user for the most “current” options instead of using the options.json file included with the hintme module. This is probably a tenuous way to get the most current options but it works for now.

I intend to add a suite of unit tests soon, and probably break up the code a bit. Releases < 1.0.0 should be considered rough drafts.

If you have any feature suggestions please leave a comment!

Modern Web Practices ebook launched!

Today is a big day for me. Today I become (dramatic pause)… a published author!

I am excited to announce the launch of the Modern Web Practices ebook, a collection of six chapters on web development forged in the fiery crucibles at appendTo!

  • Preface by Michael Hostetler
  • Chapter 1: Automate Your Workflow with Grunt by Aaron Bushnell
  • Chapter 2: Offline Web Applications by Nicholas Cloud
  • Chapter 3: Data Binding by Ryan Conaway
  • Chapter 4: Making Things Move with CSS3 Transitions and Animations by Trevan Hetzel
  • Chapter 5: HTML and CSS Bad Practices by Ted Waller
  • Chapter 6: Bower in Practice: A Package Manager for the Web by Bob Yexley

Writing anything worth publishing is a grueling process, and I am both humbled and impressed by the creativity, dedication, and enthusiasm of my fellow co-authors.

We all hope that you’ll buy the ebook of course, but we also hope that it will–in some tangible and meaningful way–help you grow and succeed in your career.

git-root

I wrote a little bash alias a while ago to help me instantly to the root directory of a git project from any directory beneath it.

It’s pretty simple. Assume /projects/foo is the root of a project under git. Assume your pwd is /projects/foo/bar/baz. At the prompt, typing git-root will return you to /projects/foo.

This works by changing pwd to be the actual .git directory under the project root, and then backing out of it one level up (to ..).

An addendum to my so-called expertise

In August I delivered a presentation called “Mastering Asynchronous Flow Control in JavaScript” at devLink 2014. To illustrate how tricky mixing asynchronous and synchronous code in JavaScript can be, I gave the following example:

bad, bad example

I claimed, incorrectly, that the error thrown in the callback would cause unintended consequences when it re-entered the catch block (well, beyond just crashing the program).

I have since had a chance to re-visit this code and realized that this example is not representative of the point I wanted to make, which is actually represented by this gist:

In this example, an async function is invoked with a callback. Inside that function a try/catch block is executed, and when successful, invokes the callback within the try block. When the callback itself throws an exception it bubbles back up into the try block and then gets caught in the catch block, invoking the callback a second time. You can see this in the console output, where the first logged arguments object contains a null error and the second contains the error thrown in the callback itself. To avoid this situation simply invoke the callback outside of the try/catch block altogether:

Now I shall go into the East and diminish.

A really good second pair of eyes

This month (October) is my two-year anniversary at appendTo. Two years may not sound long to you but in the tech world it is a bit of an eternity. My wife Brittany still can’t believe I’ve stayed that long–most of my other jobs have been project-based and have lasted a year or less. When I started with appendTo my desire was to find a place to hang my hat for a while. And here I am, two years later, and the hat is still on the hook.

I flew to Tacoma with a co-worker, Matt, a few weeks ago, to help a large, enterprise company conduct an internal hackathon for their IT support team. We functioned as technical coaches, helping each of the five teams participating to make decisions about technical trade-offs (they had two days to finish their projects), and to help mitigate any technical obstacles that arose. It was a marvelous, albeit exhausting experience. When we met with this company’s leadership for the first time I was asked to describe what appendTo is all about, and this is what I said:

appendTo’s name is a play on the the jQuery function of the same name. In JavaScript we often want to take an element, say a hyperlink or a some emboldened text, and append it to some other element, like a paragraph. Our company has a similar relationship to the clients it engages: we append to that client, becoming a part of its team, to help accomplish its goals with our own expertise and values. We are very fast, and very effective.

I was then asked about my personal qualifications as a technical coach. Each team, in theory, could choose any technology stack for their project (though each project had to function on mobile devices), but in reality the company had a significant Microsoft infrastructure. Matt and I had spent a good deal of time discussing the potential technical avenues each team might take, and we had concluded that, given the time constraints and culture of the company, Microsoft-based, cloud hosted solutions were likely candidates.

Fortunately I have experience with the .NET stack, which put the client at ease. But I also stressed that my career has spanned many stacks, languages, frameworks and paradigms, and that I had sought from the beginning to be a generalist, not a specialist. To me, understanding problems is more important than particular solutions, which may be myriad. Problems are always contextual.

The leadership team then asked what I thought about my role in the hackathon. I replied: “I am going to be a really good second pair of eyes.”

It was a decent elevator pitch.

Each team ended the week with polished projects, and though we were all tired and giddy from the process, an intense camaraderie emerged. Both Matt and I lived up to the promises we made and the client was very pleased.

I’ve since reflected on the claims I made in our initial meetings (all of which I believe), and projected them onto the backdrop of my experiences at appendTo. I’ve worked with a lot of clients, on a lot of projects, with a lot of different technologies. I’ve produced code, written articles, coached a hackathon, given presentations, migrated a mountain of WordPress data (a task I would not wish on my enemies), created and contributed to open source projects, and so on. For each client engagement I straddled the line of being uniquely me, and being that second pair of eyes; of maintaining my own personal boundaries and standards, while appending to an existing team or management structure with their own goals and values. I’ve seen my co-workers do the same, time and again, in development, design, and management capacities.

There is a time for modesty, but this is not it.

appendTo harbors amazing people with amazing talents. Moreover, it treats its employees like entrepreneurs, free to grow their ideas and visions and passions while serving clients. It’s a petri dish for excellence. And this characteristic is intentional.

When I was first hired, I was told that appendTo was a place for recovering developers who had been abused by the corporate world. And though the journey is not always smooth (no good journey is!), the work I do here and the relationships I make are, and will continue to be, some of the most significant in my life. And for that I am both grateful and humbled.

 

gogrep: Exploring go

I’ve been learning Google’s go language and I put together a fun, trivial implementation of grep (gogrep!) to explore some of the language packages. It’s not complicated; the command is invoked with a regular expression pattern and a file path, and iterates over the file, line by line, attempting to match the pattern. Lines which match are then sent to STDOUT.

Go is an interesting language, and I like a lot of its features.

Having a unified workspace for both writing code and building binaries is quite nice, though I am puzzled at how specific versions of dependencies are specified for projects, as the organization of the workspace doesn’t seem to allow for this.

Method implementation for go objects behaves in a similar manner to extension methods in C#, in that methods are not defined on a specific object, but rather as standalone functions that receive, as their target of invocation, an instance of a particular type of object. These “methods” may then be invoked on any object of that type, much as extension methods in C# may be invoked on objects to which they are not really attached, by a trick of the compiler.

Go is type-safe and uses compile time, static type checking. I rarely find myself declaring types of variables, however, because go also uses type inference to make assumptions about the types in my code. The language also supports a special kind of type-safe duck typing in which objects that conform to declared interfaces implement them automatically. Because of this you can define interfaces for external libraries and the compiler will enforce your interfaces.

Go types don’t use type system inheritance; they use embedding instead. Object embedding reminds me of prototypal inheritance in JavaScript, where an invoked method that does not exist on an instance, but does exist on the instance’s prototype, will be invoked. A key difference between the two, however, is that in JS the target of invocation (the value of “this”) will be the object at the top of the prototypal chain, whereas in go, the target of invocation is an instance of the embedded object not the object embedding it! This is not as unusual as it sounds; it is a way to extend behavior through composition rather than inheritance. (Embedding objects can “override” the methods of their embedded objects, however, providing their own implementations.) Not only does embedding grant objects the behavior of other objects, it also means that objects satisfy the interfaces of their embedded objects as well. Epic.

I’ve read a little about the go concurrency model (Goroutines and channels), and I’m eager to jump in and play around with it but haven’t yet.

Overall I’m very impressed with go as a language. Many articles I’ve read almost exclusively relegate it to system-level development, though I hope it creates a much wider footprint.

Use node to change your bash prompt

I use the bash shell with git completion on my Mac. It’s awesome except it makes my bash prompt (PS1) kind of long and ungainly:

I wanted to optimize space in my terminal, so I searched for alternative ways to display the bash prompt and found an elegant solution on askubuntu.com that reduces each directory in PWD to its first letter by evaluating the output of the `pwd` command and piping it through sed (streaming editor).

It works really well, but I wanted the last portion of the path displayed as the full directory name. I’m not familiar with sed syntax, and found myself thinking: I know how I would do this in node.js. So I copied the example, opened `.bash_profile`, and hacked up some code.

Turns out that when you invoke node with the `-e` parameter it will evaluate the string that follows. That gave me the exact prompt that I wanted:

Is it elegant? Not really. Is sed syntax more terse? Absolutely. But you know what, I do what I want and I had fun doing it. :D

And yeah, I know, zsh.