20 Jun 2013

Adventures with MRI 2.0.0 and Zlib: A Story of Malformed Gzips

It started off as a casual inquiry on Twitter:

And led to my friend @geopet posting the Minimum Viable Demo as a Gist:

And it was interesting

What we found out was that the Ruby open-uri library would make calls to an external API (Wunderground) and throw a Zlib::DataError when run in MRI Ruby 2.0.0. The strange thing was that MRI 1.9.3 works perfectly fine. Same exact story when the GET Request comes from Net/HTTP instead of open-uri. But it succeeds on 2.0.0 when using the RestClient Gem, as documented by @injekt.

The Gloves Come Off

We dove into the source of the error and determined that it was thrown from net/http/response.rb:357. In order to better understand the error, I sequentially placed binding.pry statements to determine where the error percolated to the surface. It was the call to @inflate.finish which was where the Zlib::DataError surfaced.

I left the code at this point and posted my initial findings back to Geoff and left the project alone.

Today

Then I saw this message and it was time for more digging :).

I started by forking his Gist and pulling it down to my local computer. My first phase of troubleshooting was to try alternate tools, in order to see how they dump the HTTP response. Good ol’ curl came to the rescue and provided me with the results that I placed in curl_response.txt and curl_raw.txt. Notice the rather interesting artifact around line 12 on the RAW version that isn’t present in the alternate curl response.

Pulling in Net/HTTP

It felt like progress and I wanted a better way to tweak the net/http library. I prepended the local directory to Ruby’s LOAD_PATH and copies the net folder out from MRI’s lib directory. Having the Dir.pwd prepended to the path enabled me to make very convenient testing tweaks to the Ruby Standard Library without needing to alter my standard RVM install :).

Tapping the Sockets

With net/http libs loaded from the local file, I was off to the races. I tapped into the internal workings by using the ‘sack’ utility sack for jumping directly into and editing ack results. With the addition of a strategically placed binding.pry, I was able to tap into the live socket info via a socket.read_all and write that out as a binary dump to socket_content.bin.

Reducing it to Elements

The last step in my troubleshooting was to create zlib_targeted.rb for isolating the zlib load issues from net/http. Since the underlying issue appears to be a malformed gzip returned from Wunderground’s API, I created zlib_targeted.rb to remove net/http from the equation. Check out the demo content of the file below:

Conclusion

Now we have a very narrowly tailored set of examples that dig into the exact errors, thanks to @geopet, myself, and @injekt.

For more info, see the comments in this Gist repo from @geopet: Initial Gist

Or my repo that includes the files described in this post: Full repo

I’m happy with how the toubleshooting has progressed and would like to see this issue resolved, whether it is a malformed response from Wunderground, intolerant behavior from MRI 2.0.0, or anything else.

02 Jun 2013

Don't fear pair programming - A Guide to Starting

Pair Programming is becoming a big deal in the Ruby programming world: this guide will help you get started.

Pre-Reqs:

General familiarity with Ruby tools (Bundler, Gems, RVM/Rbenv) Basic commandline comfort

What is Pairing?

In its simplest form, pair programming is where a pair of programmers work on a problem using the same computer.

Since I live don’t live in a technology hub in America, programming in the same physical location is challenging. Instead, it’s possible to replicate that experience with both parties in separate locations.

How Does it Work?

Setup a video call using Skype, Google Plus, Twelephone. Both partners connect into a shared machine such as a Virtual Private Server (VPS). Each partner connects into a shared Tmux session. Both of the individuals can jointly edit the same files, as if they were present at the same keyboard.

Setting It Up From Scratch

Signup with a VPS provider (I’m currently very happy with DigitalOcean) Boot up a basic 512MB RAM instance in the Linux flavor of your choice. I’ll use Ubuntu 12.04 x32 for this example. Once the instance is booted up, let’s connect and setup basic sane defaults. Install tmux and vim-nox using the package manager. Install Ruby using RVM, Rbenv, or Chruby. Install Tweemux Gem - gem install tweemux Now that we’ve laid the groundwork for it, let’s work on making it available for a partner.

Inviting a Pair

When ready to invite a pairing partner, we start by adding a unique user for them. For convenience, it’s best to add their username from Github.

adduser --disabled-password $PAIRNAME

Next we’ll use the Tweemux Gem from RKing to pull down the partner’s public key from Github, and add it to their ~/.ssh/authorized_keys.

tweemux hubkey $PAIRNAME

At this point in the process, that user can login to your server using the IP address, their Github username, and their matching private key.

ie - ssh $PAIRNAME@IP_ADDRESS_OF_SERVER

At this point, the host should fire up a shared Tmux session:

tmux -S /tmp/pair

And enable that socket to be world readable:

chmod 777 /tmp/pair

NOTE: Doing this on anything other than a bare server, or with someone you don’t trust, isn’t a secure or a good idea. Don’t do this on a production server or with sketchy folks!

Next, it’s time for the guest to join the shared Tmux session:

tmux -S /tmp/pair attach

And you’re both in the same Tmux session! The view, keyboard and such is all shared =).

26 May 2013

Buff - A Gem that Puts Muscle in the Buffer API

It’s Done! Buff is a Ruby Gem that wraps the Buffer API.

Why Write Buff Gem from Scratch?

Because the current Buffer Gem doesn’t have full coverage for the API. I started to update the Buffer Gem but quickly realized that I was spinning my wheels. I wanted to implement the gem as a set of layered abstractions and to be able to process the responses using Hashie::Mash. I envisioned a Gem where each response was a first class Ruby object, where each nested key could be called as a method.

I realized that it would be cleaner and more expedient to code from scratch: I spent the next few hours and produced a gem that had feature parity with Buffer’s existing gem:

Introducing Buff, the API complete Ruby Wrapper for BufferApp.com. Buff muscles Ruby into Buffer’s API.

Buff is RSpec tested, Webmocked, Travis CI’d, and easy to use.

Setbacks and Triumphs

It wasn’t all roses and perfume in the creation of this gem. Three setbacks stand out in my mind.

Webmock

I’ve previously used VCR for testing web APIs, but wanted to use a new system to build new skills. Webmocks are very pleasant to use and allowed the Specs to verify what API was contacted, along with testing the body content and return values.

HTTP Libraries

Buff Gem started with HTTParty , which was splendid while implementing the HTTP GET API methods. Once I began implementing the HTTP POST requests I started experiencing discomfort with using HTTParty. It’s a reliable library but I didn’t gel with the DSL for describing HTTP requests. Thankfully the HTTParty calls were wrapped inside the post and get methods in Buff::Client::Core.

Since the code was tested with Rspec and the post and get methods were abstracted, swapping out HTTParty for Faraday was merely a one hour setback.

What a wonderful confirmation that it’s valuable to wrap external library calls in an abstraction method inside your own library. This made dependency swaps much simpler.

Creating correct “application/x-www-form-urlencoded” Data

I expected to find a Standard Library tool for converting a nested Hash + Array object into www-form-encoded data. I was sorely disappointed, looking at you Addressable Gem, and spent hours trying to find an already coded solution.

After stepping back from the code for two days, I was explaining the problem to non-technical coworkers. In that moment, my subconscious presented the answer. I realized how easily I could write the transformation myself. I mentally coded it on the way home that afternoon and wrote it in bytes that evening. Here’s the implementation from Buff::Client::Encode:

Moral of the story : When stumped, back off and solve another problem. The subconscious is a useful ally. Hours of struggling could have been saved through patience and getting other things done.

What’s Next?

Since the Buff Gem provides greater coverage of the Buffer API than the existing Gem, it’d be awesome to see it replace Buffer Gem as the official Ruby Wrapper.

I feel great about completing a Gem with 100% coverage of an HTTP API :).

I’m considering writing a couple of small Buffer CommandLine tools for easy posting. If I have more steam, I’ll add an Alfred Workflow on top that allows posting to Buffer!

Want a Demo of Using Buff inside Pry?

If you work with Bufferapp and want to adopt this Gem as your Official Ruby Wrapper, that would be snazzy. Let’s talk: @_ZPH or Zander!

26 May 2013

Starting with Vim

[caption id=“attachment_712” align=“alignleft” width=“500”] By: Niklas Gustavsson[/caption]

It’s been two lovely years with Vim and I’m sold! Vim’s the straight edge razor that slices through code. It’s like having a finely crafted and personalized lightsaber.

This post is aimed at getting a new Vim user up to speed without cutting off or wanting to sever their hands.

Getting Started

  • Use GVim or MacVim (avoid Terminal Vim until more proficient, then generally avoid GUI Vims)
  • Learn the Vim Modes
  • Learn survival tactics ala Progressive Vim
  • Learn to serenade this wild beast called Vim in its own language
  • Add plugins

I’ll assume that readers of my blog can install GVim or MacVim on their own. On OSX it’s as simple as using homebrew. On Linux, use the awesome package manager of your choice.

Vim Modes

Vim is a modal editor. You have three essential modes of operating:

  • Insert Mode (used for typing)
  • Visual Mode (used for selecting)
  • Command Mode (used for executing commands/movements)

Having three modes means that the keyboard can have 3x the number of functions because each key can have an alternate meaning in the various modes. For example, take the letter ‘i’:

  • In command mode, i places the user in insert mode
  • In insert mode, i types the letter i
  • in visual mode, it appears not to do anything (I could be wrong, but 10 secs of testing back me up)

The first thing to learn is a lesson from Douglas Adams: “Don’t Panic!”.

When lost in Vim or things are going wrong, mash ESC until you’re back in Command Mode.

When a file gets messed up because you’re unfamiliar with Vim, type ESC followed by :q! This will quit the file without saving changes (forced quit). If the changes are important, enter command mode with ESC and type :wq to write the changes to disk.

When you’re ready to type into the text file, type i to enter insert mode. At this point, typing will proceed as normal until you hit escape to leave insert mode.

Pat yourself on the back

You’re now as accomplished as I was for my first year of dabbling with Vim!

I didn’t realize how little of Vim I knew until I saw the surgeon’s precision with which Gary Bernhardt wielded Vim. As soon as I saw this I wanted more.

I took his advice and started paying attention to the language of Vim, which largely consists of unmodified alphabet keys and shifted alphabet keys. Learning some of these has made my typing DRASTICALLY more efficient. I now feel very little resistance when typing. It’s as if my thoughts are able to leap onto the screen without obstacles. It’s magic folks! And you too can cast these spells with enough time and effort.

But mastering Vim (or at least becoming proficient) is a longer topic than I can cover in this post. So let’s move on to discuss plugins and the .vimrc.

Vimrc

Let’s get this out of the way: Vim’s not terribly friendly with the default configuration!

So what’s the solution? .vimrc and Vim plugins.

The .vimrc file goes in your home directory, ie ~/.vimrc, and dictates Vim’s configuration. You can tweak the colorscheme, the timeoutlen, and just about anything from here. Here’s an example of what’s in my own .vimrc:

Plugins are re-usable Vim code that has grown too large to be included in the Vimrc. Plugins extend the functionality of Vim and can make it act more like an IDE. There’s currently a vibrant community of Vim users and a growing number of Vim plugins.

Here’s a list of My Current Plugins repo:

And here are the ones that I use daily:

ack.vim
ctrlp.vim
delimitMate
gundo
slimux
supertab
sweet-rspec-vim
vim-bundler
vim-commentary
vim-detailed
vim-dispatch
vim-endwise
vim-eunuch
vim-fugitive
vim-git
vim-numbertoggle
vim-powerline
vim-rails
vim-repeat
vim-rspec
vim-ruby
vim-ruby-refactoring
vim-surround

Hope this helps get someone started in Vim. It’s a very rewarding and sometimes frustrating journey.

I’d love to help my readers learn Vim! Let me know about your stumbling blocks and difficulties in the comments or on Twitter @_ZPH

06 May 2013

Travel Advice You Can't Afford to Miss

[caption id=“attachment_692” align=“alignleft” width=“500”]By: Frontierofficial By: Frontierofficial[/caption]

Traveling in a foreign country can be filled with wonder and excitement. It can also turn into a nightmare without the right preparation.

Travel Tips

  • Bring currency (US / UK / Euro) in decent quantities in small bills ($500+). This is emergency money for towns without ATMs.
  • Carry that currency distributed among various hiding places on your person and in your luggage. Consider getting extra hidden pockets sewn into some of your pants.
  • Wear easily washed clothing. Quick dry fabric is very convenient when forced to wash clothing in a hostel’s sink.
  • Bring all purpose liquid soap. I’m talking about hippie soap here like ‘Dr. Bronner’s’. It can be used for washing your body, your hair, and your clothing.
  • Keep only enough currency for a day or two in your wallet or purse. If someone pickpockets you, you’ve lost very little and have a story to tell.
  • Be skeptical of people who approach you. Some are great awesome people, others are hustlers. Learn the difference.
  • Be more trusting when you approach people. I made a habit of choosing my taxi drivers rather than choosing the ones who were overly interested in me.
  • Avoid the heavily touristed areas and densely populated areas. Pickpockets and scams will be more prevalent where a higher density of marks exists.
  • Withdraw currency from ATMs in well lit areas.
  • Use ATMs instead of currency exchangers. You’ll tend to get better rates.
  • Bring a good little flashlight and headlamp, especially when visiting areas without much infrastructure.
  • Shoot plenty of photos, especially of people and local vibrancy. Landscape photos won’t have the same staying power.
  • Write a journal or blog while traveling to share your experiences with those back home.
  • Contact your banks and credit card companies before leaving. Let them know the locations of your visit and the duration. This minimizes the risk that the cards will trigger fraud alerts while traveling.
  • Leave a photocopy of passport, credit cards and any other travel paperwork with a trusted friend or family member. Keep a second photocopy set in your luggage.
  • If you want or need connectivity while away, bring a GSM unlocked phone. In the US, a phone from AT&T that’s unlocked would be a decent choice.
  • Learn basic internet safety and use a VPN or SSH Tunnel for routing your data when on unknown internet connections. Better safe than hacked.
  • Consider using 2 Factor Authentication if you must use an Internet Cafe to log into your email. Even with this protection, try to avoid it.

What other travel tips have you used to make foreign travel a smoother process?

If you want to engage in Extreme Retirement Planning, living abroad on $600 - $1000 / mo and retiring early wouldn’t be too horrible ;) Especially with a remote job!

04 May 2013

Privilege Means Responsibility

Let’s redefine privilege

Because it’s not working well for our society. Here’s what we have right now: Privilege : advantage, benefit; prerogative, entitlement, right; concession, freedom, liberty. Advantage, benefit, freedom, liberty: those are all accurate words for what I disproportionately enjoy with being a privileged member of society. In fact, I’ve got just about all of the social advantages that one could ask for with being white, male, able bodied, living in a well off country and a few other choice characteristics. I rolled mostly 20 in this attempt at life. Because of my family’s assistance and scholarships, I also had the advantage of completing my Bachelor’s Degree. Did I mention that my parents both had college degrees or better when I was young?

Where this puts me in life according to statistics:

According to US Census data from 2010 median income varies significantly along ethnic lines:

  • White = $54k
  • Black = $32k
  • Hispanic = $37k According to US Census data from 2009 that compares income of full time workers based on education and sex for my age:
  • Male = $67k
  • Female = $52k How about the fact that during my childhood, I had one parent with a professional degree and one with a bachelor’s degree? Poverty Based on Parent’s EducationTo summarize, statistics indicate that I earn $1.69 for every $1 that a black person will earn, $1.29 for every $1 that a woman earns, and my odds of being a child in poverty were ~ 1/4 that of a child raised by parents without a high school diploma. This is purely a function of my genetic and socio-economic background not about any shred of my own accomplishments. It bears repeating that the fact that I have an advantage in earning power as outlined in this paragraph has nothing to do with my own merit. Want to argue these statistics? A study found that transgender women earned 32% less on average following their transition from male to female! SourceI’ve faced some challenges in life, but they’re a lot easier to overcome when playing with a stacked deck.

I’m Privileged So…

I’m introspective enough to admit that I haven’t always been as aware of my advantages as I am now. Being a few decades into life, living meagerly for a decent chunk of my twenties, and traveling outside of the United States has opened my eyes. Having friends who are different than myself has opened my eyes. Listening to smart people who have huge hearts has also opened my eyes. Witnessing people who live in abject poverty has opened my eyes. And this process isn’t over, I’m still learning. A couple of months back was my first exposure to the term ‘ableism’. I hadn’t previously considered that calling someone ‘dumb’ harkenens back to this definition dumb : offensive (of a person) unable to speak, most typically because of congenital deafness: he was born deaf, dumb, and blind. Or that using the word ‘insane’ as a pejorative probably refers to individuals who suffer from schizophrenia and who historically faced persecution and death.

I’m still learning

I’m proud of where I’ve gotten to in my approach to the world, but I want to share an example or two of my own past prejudices. I share them not because I’m proud of my behavior, quite the contrary; I share them to show that it’s a learning process. When I was in elementary school, I remember seeing another child on the basketball court. In most respects, he appeared quite similar to me. But his elbows and arms were covered in scaly, reddened skin that cracked and bled. I remember my revulsion and how I avoided him. I can’t say that I thought much of that child after moving on from elementary school. I became busy with school, friends, baseball and listening to music. In high school I started having to deal with my own challenge in life called psoriasis. Psoriasis is an autoimmune disorder where cells reproduce much faster than normal, causing intense itching and discomfort. It wasn’t until a few years into dealing with psoriasis that it dawned on me: that child who I avoided suffered from the very skin disorder as I did.

Join Me

As it stands now, I’m playing the game of life with a stacked deck. I face less consequences for raising my voice in support of individuals who don’t have that luxury. I have better financial resilience to deal with social opposition as I work towards better equity in our society. It’s not only my choice to do this, it’s also my responsibility that comes with the hand I was dealt. I’m going to take a stand on issues of gender equality, racial equality, sexual orientation equality (and more broadly the right to be yourself), disabled rights, bullying, and marginalizing behavior. I may not get it all right, but I welcome receiving feedback so that I can improve. The next time you see someone use a pejorative based on race, disability, sex, or someone bullying another individual:Don’t fucking let it slide! Stand up and lend your voice to the conversation. Your voice offsets the hatred and bigotry that is being leveled against someone. You’ll be glad you took a stand and you’re making this world of ours a better place.

02 May 2013

Hack Your Finances - Thoughts on Extreme Retirement Planning

Extreme Retirement Planning is a financial movement that I discovered a few weeks ago. At least, that’s when I heard of that terminology for being frugal. As it happens, I’ve been implementing some of those ideas for the past year or two. But these Extreme Retirement Planning (ERP) folks crank it up to 11 and that’s where I have something to learn.

Concept in a Nutshell

  • Save as great a % as possible (up to 85% or more) of net income (post tax dollars).
  • Live off as little spendable income, including cutting out luxuries and vehicles, to the greatest degree possible.

What’s the result? Being able to “retire” in 4-15 years on the lower level of income that the ERPer has become accustomed to.

What Does This Mean for Me?

If I can live off of $1000 / mo while putting the rest of my take home cash into savings, for the next 7 years, I can retire in 2020. And by retire, I mean live off of the expected 4% growth on my principle even after factoring in 3% inflation. Then at that point, any income that I make is free to fritter or save because my daily costs are taken care of.

Assuming that there are two people working at this level of income, then living off $2000/mo as a family isn’t too tough in some parts of the country. And retiring in 7 years wouldn’t be too bad either :).

I’ll explore this concept more as I dig into trimming my excess spending.

Credit for the concept and basic calculations goes to Mr. Money Moustache.

29 Apr 2013

Goals and Giving Back: Creating Meaning in Life

[caption id=“attachment_599” align=“alignleft” width=“500”] By: John O’Nolan[/caption]

I’ve been in serious discussions with a new friend regarding the refinement of the self. The discussions started at RubyMidwest but since I don’t yet have their permission, I’ll leave the individual as a shadowy anonymous figure.

The evening of the discussion brought about a conversation regarding refactoring oneself through a constant process of testing and revising.

I shared my own experience of setting actionable goals related to various facets of my life, a choice that was influence by 7 Habits of Highly Effective People. These goals run the gamut of goals, anywhere from family, friendship, business, personal knowledge, technical skill acquisition, etc. Each of the goals is categorized and provides a broadly sketched roadmap of what I want to apply my energy to during 2013.

Without going into all of the details, I’d like to provide a couple of examples.

One of my larger goals for the year is to be less of a consumer and more of a producer. This applies both in the technical world, where I want to write more code and blog entries (rather than simply consuming them) and also in my online social experience where I’m moving out of my introverted shell and making connections with likeminded individuals. Thus far, this goal has been a smashing success. I made new Ruby friends at RubyMidwest and I’m a much more active member of the online community. I’m pleasantly surprised that this is such a natural goal to work on. It has become an outlet of my energy that’s relaxing and fulfilling.

In this same vein, I’ve become increasingly interested in giving back and contributing via teaching or volunteering in order to help others along their path. Pragmatic Thinking and Learning cites the Dreyfus Model of Learning, which loosely paraphrased, indicates that because I’m a beginning intermediate programmer, I’m uniquely prepared to lend a hand to beginners. The fact that I’ve been teaching myself Ruby for the past 3 years means that beginners’ struggles are fresh in my mind. So I’m taking what time I can out of my schedule to lend a hand to the next generation of passionate programmers.

Perhaps in the not too distant future, I’ll have a work setup that encourages and allows me to spend a portion of my time giving back to the community. The time’s approaching where I won’t be able to resist the allure of professionally joining the ranks of software developers.

If I may breach the fourth wall, what are your goals and aspirations gentle reader? I’d love to hear about them in the comments or in the walled garden of Twitter @_ZPH.

PS - Start mentoring someone, now!

24 Apr 2013

Stop, Drop, and Sleep

Exhaustion is in the air today. I fell asleep at 7pm and according to my Twitter feed, it’s not just me.

So is:

Passed out on the couch at 9. Been working so much lately :/

— ashe dryden (@ashedryden) April 24, 2013

And:

to code or sleep? that is the question.

— Derek Bender (@djbender) April 24, 2013

And Later (live update while blogging):

feel in all sorts of squinty. rest is coming.

— Derek Bender (@djbender) April 24, 2013

And Even:

@elight @_zph @centipedefarmer @bantik @kerrizor methinks I may be a bit tired.

— PJ Hagerty (@aspleenic) April 24, 2013

We’re exhausted!

[caption id=“attachment_588” align=“alignnone” width=“500”] By: umjanedoan[/caption] Exhaustion has become the norm. Take my own evening last night as an example. We had a long day at work and I was spent by the time I arrived home. After running a necessary errand, the hour had pushed towards 9PM, which meant dinner was going to be a cursory affair. You, my gentle reader, might expect me to crash into an uninterupted slumber at this point in the story. Unfortunately, I didn’t. I spent the next ~ 3 hours reading tech news, catching up with friends on Twitter, and staring semi-comatose at my laptop monitor. I tried to work on learning new programming techniques, but it wasn’t sinking in, nor did I have the requisite motivation. I collapsed into bed sometime after midnight and woke feeling groggy and spent. I’ve been reflecting on the WHY of this behavior and it’s the motivation for this blog post.

WHY

I spend a fair bit of effort in life considering my actions and the outcomes involved. I try to play these in the right manner to “Optimize for Happiness(TM)” as @erniemiller so eloquently stated at RubyMidwest 2013. But I didn’t follow through on the logical process last night because in addition to needing rest, I also needed to decompress and stimulate my mind. I’m going to go out on a limb here: I think that my reluctance to fall asleep is endemic of our social expectations in a slice of American society.

Work Longer, Faster, Smarter

Living in a culture that idolizes workaholics demands a special response from those of us who yearn to maintain a work-life balance. Especially when prone to hard work and long hours, stepping back and turning off can be a challenging habit to cultivate. I’m not sure what the right response is when we have competing pressures in life, beyond making the best decisions available given the resources at that moment. And with each decision, reflect on the behavior and outcome to determine if it should be repeated. The right answer for me that night was probably a bit of interracting with friends on Twitter (no more than 60 min) followed by time with kittens and my partner. Lesson learned, hopefully :). I’d love to hear tips and feedback for how you, my reader, addresses this. Leave a note in the comments or shout at me on Twitter: @_ZPH.

20 Apr 2013

Increasing Productivity with Shortcuts

[caption id=“attachment_582” align=“alignleft” width=“500”] By: Dennis Hamilton[/caption] I’m writing this to the incessant tick-tock of a digital Pomodoro, which seems fitting as this post will discuss productivity hacks. We won’t be talking about run of the mill ones. I won’t berate my readers to modify their ‘/etc/hosts’ file in order to route Reddit or Twitter to localhost. No, these are real habits that help me be happier and more productive with the time that I spend on a computer.

Pre-Hack Step

Have a goal. Know where you’re heading and why. Act intentionally. This has been driven home to me by my own experiences in life. Recently, I’ve been reminded of this concept by the wonderful book, 7 Habits of Highly Effective People. In it, the author paints the picture of chopping through a forest without knowing what cardinal direction one is following. If you’re trying to learn a new technology, set actionable goals for yourself and talk about it with friends and colleagues. If you’re working on personal relationships, admit that to yourself and push yourself to be better.

Technological Hacks

  • Make everything a shortcut. I accomplished this by following Steve Losh’s article On the Cadet Keyboard. I configured my MacBook Air’s keyboard to use the right Alt key as a hyper key (a chord combination of 4 modifiers). This yields a unique key namespace for setting up non-conflicting keyboard shortcuts.
  • Use a program like Keyboard Maestro or BetterTouchTool to setup shortcuts for all of your regular programs. For me these are iTerm2, Chrome, Finder (or alternative), ThinkingRock, Email Client etc. My terminal is never further away than a HyperKey-T and possibly a Cmd-N to create a new window.
  • One keyboard shortcut that stands out on my system is a keybinding via Sparrow’s preferences. The combination alternately brings Sparrow to the front, or hides it. This is amazingly useful in order to not lose as much energy in context switching. In a matter of 4 seconds and by mashing the same key combination twice, I can check on a new email and then relegate Sparrow to the background.
  • Make great use of Alfred.app! Use custom searches for common items (ie Google search becomes “g searchterm”, note that this is built into Alfred). Add your own shell scripts for common tasks, ie checking for information on a public website via a prefilled URL. Use Alfred to execute regular shell commands by prefixing the command with a “>”. For example, I added a Ruby script to my ‘~/bin’ directory that sends an email to my dedicated GTD account. I access the script from Alfred, fire off a note for later, and am back to my current task without much distraction. This is a great way to keep your mind empty and receptive (just make sure to process the GTD tasks in a timely manner). Have more productivity hacks? I’d love to hear them in the comments below or via Twitter @_ZPH. I’ll post at some point about my experiences with the Pomodoro technique, but at this point it’s too early for me to comment.