Rockin' good code, rockin' good times


Apple announced a new language last week: Swift. Now that everyone’s had time to read the book and start playing with sample projects, a startling deficiency of the language has been uncovered. Swift makes no provision for access modifiers such as public, private, or protected.

This isn’t altogether surprising. ObjC has no access modifiers (for methods or properties, anyway). Knowing what’s “public” and what’s “private” has largely been a matter of convention — public stuff gets put in the header file, private stuff in class extentions. Swift doesn’t have headers, and hasn’t been out long enough to establish conventions, so what’s an early-adopter to do?

Enter protocol

It’s important to note that, when one talks about making a “private method” in Swift or ObjC (or ruby or java or…) those methods aren’t really private. There’s no actual access control around them. Any language that offers even a little introspection lets developers get to those values from outside the class if they really want to.

So what we’re really talking about here isn’t access control modifiers as much as a way to define a public-facing interface that merely presents the functionality we want it to, and “hides” the rest that we consider “private”.

The Swift mechanism for declaring interfaces is the protocol, and it can be used for this purpose.

A Type-Oriented Language

At first it’s not very clear how this helps the situation. But remember that Swift is very strongly typed, and that protocols, themselves, are first-class type citizens that may be used anywhere a type can. And, crucially, when used in this manner, a protocol only exposes its own interface, not that of the implementing type.

Thus, as long as you use MyClass instead of MyClassImplementation in your parameter types, etc. it should all just work:

As you might already see, there are some cases of direct assignment where you have to be explicit with type instead of relying on Swift to infer it, but that hardly seems a deal breaker:

The Need for Private

And really, while I’ll need to get more Swift code under my belt before I can form a strong opinion on the matter, I suspect the need to encapsulate implementation details will be a lot less pressing in Swift than in ObjC.

In ObjC, outside of the rare case of publishing a public API or the like, the public/private divide was as much about organizing code as it was anything else. And Swift gives us many more arrows for our organizational quiver — closures, nested functions, nested classes, nested types, methods for enums and structs…

For that outlier case of publishing a public-facing interface? Using protocol is semantic, reasonably concise, and to my eyes looks a lot like the class extensions we were already using for this purpose in ObjC.


Welcome back to my final post on Apprentice Challenges, this time focused on company-specific issues.

Before I began working at Reverb, I imagined that most of the obstacles I’d face would be technical in nature (in fact, my first blog post mentioned Vim as my only example of a Reverb-exclusive challenge), but after four months on the job, the biggest hurdles I’ve overcome have been non-technical. As such, the “company-specific” issues I’ll focus on will actually be soft skill challenges encountered at Reverb but with takeaways that are universal.

Soft skills are those which relate to emotional intelligence and behavior, often distilled to “empathy”. The specific challenges I faced were focused in two areas, learning/teaching styles and communication.


As an apprentice, my primary job responsibility isn’t coding itself but learning how to code better. That said, Reverb is a small start up with a small (currently 5-person) dev team, so there is a big focus on productivity. In an environment like this, ability to learn on the job is of utmost importance. But learning on the job is a two way street; I have to rely on my mentors (in this case, the rest of the dev team) to help me out when I get blocked so that I can learn quickly and remain productive.

It’s obvious in hindsight, but adapting to the various teaching styles of the other developers is a task that required pointed reflection, discussion, and old fashioned trial-and-error. I think we’re synchronized to the point of acceptable efficiency now, but originally a series of conflicts arising from a “tough love” teaching style meant to motivate and accelerate my learning ended up having an opposite effect.

When confronted with this style of teaching, I felt pushed onto my back foot, generalized and judged unfairly. Feeling unjustly criticized, I spent substantial time contemplating these interactions, significantly decreasing my productivity on days when this occurred.

Ultimately this effect was easily reversed when we had an explicit face-to-face conversation about learning and teaching styles and I now feel accepted, supported, and motivated in ways I was not originally. The experience emphasized the importance of understanding the ways in which you most efficiently learn and the teaching styles that best allow you to improve. Of course, this takeaway relied on what is probably the most universally important soft skill out there: communication.

Without openly communicating about teaching/learning styles, my co-worker and I would probably still be mis-communicating on a regular basis. It’s incredibly important to be proactive in your communication, especially when starting a new job. Having a scheduled one-on-one meeting with a mentor/boss is very helpful in creating a set time to discuss your experiences at work, but don’t rely on this if you are confused about something impacting you immediately. Speak up! Your co-workers won’t know how you’re doing unless you tell them.

Being proactive in communication means discussing not only gripes but also successes and wins. Positive feedback is important across teams and regardless of management hierarchies. Be thankful and congratulatory; Fostering a supportive, positive, trusting company culture has benefits beyond the obvious social perks that come from a happy work place.

That said, it’s not always easy to create such an environment. Kindness in the workplace, especially in tech, is not always a given. Empathy is a skill, not a gift, and it takes practice and effort to perfect. Be conscious about your interactions at work. Giving feedback is probably the biggest hurdle for most developers regarding communication. At Dev Bootcamp we practiced giving feedback that was Actionable, Specific, and Kind (ASK). Try to focus on these criteria when preparing to give feedback to someone.


As an apprentice, or in any other position that requires learning on the job, be conscious about learning and teaching styles in order to maximize your productivity. Of course, in order to do so you’ll need to communicate proactively, which is often easiest in a supportive company culture. Companies that focus on kindness, fostering trust between employees with the help of Actionable, Specific, and Kind feedback, are commonly those with the most supportive cultures.

Thanks for turning in to my final apprentice-focused blog post! Feel free to share your experience or drop me a line to chat more in-depth at


Creating a File

LightTable’s behavioral innards are written almost exclusively in ClojureScript. So if we want to start poking at them, the first thing we need to do is create a .cljs file. I’m calling mine “understanding light table.cljs” (you can find the gist here), but feel free to name yours according to your own customs and beliefs.

Namespace and Requires

This is Clojure, and that means namespaces. We’ll need Light Table’s object library. And because macros are weird in ClojureScript, we’ll need to require those separately as well. Like so:

Feel free to alias the required namespaces as you please. But because the purpose of this post is understanding how Light Table works, I’ll avoid that bit of indirection in my examples.

Making Connections

Go ahead and evaluate that namespace expression (⌘↩︎, by default). Light Table will automatically try to connect to a client REPL. If this file were part of a leiningen project, it would use that. But seeing as it’s not, it asks you to manually connect to a client:

No client available.
We don’t know what kind of client you want for this one. Try starting a client by choosing one of the connection types in the connect panel.

Luckily, Light Table provides a client specifically for evaluating expressions in the context of itself. It’s called “Light Table UI”. Select it from the list, and try evaluating the ns expression again.

Objects Defined (And Instantiated)

Classic OOP thinking might define an “object” as “state coupled with the behavior that mucks with it”. Light Table decouples state and behavior. In Light Table, objects are responsible for state only.

Similar to the standard OOP practice of defining a class that gets instantiated into a new object, the first step of creating an object in Light Table is to define an object template:

This creates a template with a type of :reverb.lighttable/my-template-name, a tag of :my-tag-name, and then whatever state-holding properties we choose to give it.

I should probably say something about tags here. Tags are just a way of grouping objects that’s not coupled to said objects’ type or IDs. This will make more sense once we get to associating behavior with objects, which is customarily done through tags. But for now, think of a tag as a potential mount-point for future mixins.

So, in a common theme you’ll notice all throughout Light Table’s object model, object templates are just data structures. After evaling the above, you can inspect it with the following:

As you can see, the template is just a simple map. Nice!

Once you have a template, you instantiate it with create:

You can check it out with:

So objects in Light Table are very much like the templates they’re instantiated from. create just adds a unique :li.object/id key, some properties to handle behaviors (more on behaviors next!), and stuffs the whole thing into an Atom. No magic. Just data structures.

Doing Things

If objects just hold state, how do we get them to do anyhting? Why, with behaviors, of course! And for creating behaviors, lt.macros/behavior is our go-to macro. It takes a name, some triggers (we’ll get to those), and a :reaction, which is essentially what you want the behavior to do:

Inspecting behaviors is also straight forward and is also just data:

Of course, a behavior doesn’t do you a lot of good unless you add it to an object. For the sake of having something illustrative to eval we’ll use lt.object/add-behavior!. But be aware; this is generally not the best practice.

If you re-eval your object at this point, you’ll notice it now has extra data in its :listeners and :behaviors keys.

Okay. So far, so good. But seriously. How do we freaking make an object do something?

Remember that trigger you gave your behavior? You activate the behavior of an object by raiseing one of the triggers of the associated behavior:

Note that the first argument passed to the behavior’s function is the object itself. But you can pass in others in the raise:

But Don’t Do Things Like That

Here’s the problem. Behaviors added with add-behavior! can get clobbered whenever Light Table reloads its own behaviors. So the proper way to associate behaviors with objects is the way Light Table does it: in a behavior file like “user.behaviors” or the “.behaviors” file included with plugins.

When you reload Light Table’s behaviors, you’ll find this behavior automatically gets attached to any objects with the given tag.

You can even specify arguments in the “.behaviors” file:

Which get appended to the behaviors arguments like so:

So… Why?

To sum up, you create an object template that specifies some state and :tags. Then you create behavior with some functionality and :triggers. You associate those behaviors to any instantiated objects with the given tag in one or more .behaviors files. And finally, behaviors attached to objects have their functionallity invoked by calling raise with the appropriate trigger (or, more likely, having Light Table call raise with a given trigger in response to user input).

That seems like a crazy amount of abstraction to wrap your head around for what could be a simple (do-thing my-stuff), right? But the benefits along the axes of customization and flexibility are pretty extreme. If you think about it, any part of the chain from tag→object→trigger→behavior→state can be redefined without disturbing its neighbors. Not only that, it could be redefined and reevaluated at run time to modify the behavior of Light Table while you’re using it.

That’s a pretty cool trick that makes developing for Light Table just as much fun as the Clojure it’s built on famously claims to be. But it also gives the open source community a lot of freedom to extend the editor in ways the original developers never anticipated.

And that, for me, is the most valuable attribute a text editor can possess.


Here’s a fictional controller that loads up a few variables for a dashboard-like view.

  class MyController
    def index
      @products = Product.where(price: params[:price])
      @total_price = @products.sum(:total_price)
      @show_admin_bar = current_user.admin?
      @products_by_type = @products.count(group: “type”)

This type of controller tends to grow in size and complexity as new features are added. Soon you’re up to your ears in instance variables that are set so the view can render various bits.

What’s wrong with instance variables?

  1. An instance variable doesn’t complain if it’s nil. You could easily misspell the variable in your view and never really know about it.
  2. If generating the values assigned to them gets complicated, you end up littering your controller with unrelated private methods. Instance variables resist refactoring.
  3. You will end up with lots of controller specs asserting on assigns. Controller tests are harder to read because there’s a lot of noise about http verbs, params, and assigns. 

The solution? Extract an object.

Some people call these Presenters or View Models.

  class MyController
    def index
      @my_view = params[:price])

  class MyView
    def initialize(price:)
      @price = price

    def products
      @products ||= Product.where(price: @price)

    def total_price


Happy Friday.


In late January I began an optimistically-paced series of blog posts on challenges faced by apprentice developers. Today I’d like to pick back up with a focus on improving tech-specific knowledge.

Originally I explained:

“There are going to be a lot of tools and methods with which new programmers are unfamiliar or not as capable as necessary. For instance, I’ve spent a significant portion of my first three weeks improving my understanding of test-driven development using mocks, stubs, and libraries that aid in this process (eg VCR for API calls).”

After three months on the job, I can say even more confidently that this is a huge challenge faced not only by apprentices, but by all developers (though it is certainly a more difficult challenge for newcomers). We must be vigilant to keep up with new technological developments, regardless of whether the updates are for the language we write, the tools we use, or new apps being launched. It is the job of a developer to determine the best tool for the job and subsequently, to develop an awareness about what tools are available.

Apprentices are in the unique position of having a comparatively tiny set of  tools so we need to work as quickly as possible to learn the tools for our job. To this end, I have two suggestions: practice, and focus.

Practice is THE way to learn about new tools. The power of learning by doing cannot be overstated. Whether you are struggling to learn a new language or tasked with integrating a new API, the most effective way to improve will be using the tool you need to master.

There are several ways to do this. The most obvious is learning as you go. This is generally an efficient use of time, but often circumstantial pressure requires a more expedient solution. In this case, I recommend a “breakable toy” which allows for practice without the pressure of clients or management.

Note that reading documentation, watching videos, and going to meetups are all important additives, but prioritize them as supplements and not your primary method of practice.

The second recommendation I have involves focus. The limitless possibilities afforded by coding make being an apprentice extremely exciting. There are literally an infinite number of topics to discover and explore, all of which could help you grow into a knowledgeable software craftsman.

However, this benefit of code as a career can have the unfortunate side effect of distracting the novice programmer. It’s very easy to try investigating so many topics that you spread yourself too thin and end up impeding both your learning and your productivity. Realize that as an apprentice, any learning you do will be beneficial, and that it generally makes sense to focus on the topics that also make you a good employee. This might be difficult if you work for a consultancy, but for any other apprenticeship, become the best you can be with the tools and languages used by your employer and stem your curiosity on other topics until you’re more proficient at what you use daily.

When you practice regularly with appropriate focus, you end up growing at a more rapid rate. Ultimately you’ll prove yourself to your employer quicker, and be able to hasten your pace of learning by training on the topics with which your mentor can assist.

Stay tuned next time for the final post in this series, which will focus on company-specific challenges and wrap up with any miscellaneous advice for apprentices


If you’re interested in becoming a better software developer, there are well worn paths and pedagogical methodologies that can get you there. You can go to school, find a mentor, write code, get involved in open source, get a job — all of these are accepted ways to improve your skills.

I’m not here to talk about any of them. This is the first post in a series where I’m going to explore interdisciplinary paths to improving your skill as a software developer.

Why You Should Read Books Unrelated to Programming

Writing software is an act of communication, and through reading we are exposed to different modes of thinking and communicating ideas.

Through reading and expanding our vocabulary and understanding of humanity we can improve the quality of our communication in code as well as in our everyday interactions.

If you agree that naming things is one of the hardest problems in computer science, then you need tools in your arsenal to describe the abstractions we’re asked to create every day. There’s no better way to do that then to expand your vocabulary by reading more books.

What You Should Read

Read the classics of fiction, paying special attention to their narrative arc and the way they use language to bring the story to life. It will serve you well when you need to name your next class or method.

Read complex Russian literature that requires you to keep track of characters with multiple names, uncertainty in outcomes, and unclear motives. It will serve you well when you have to understand complex code interactions and architectures.

Read non-fiction about psychology, sociology, or any field that engages with humanity that you’re ignorant of. It will challenge your world view and expose you to ideas you don’t come across in your everyday life. This can help build empathy for your end users and other software developers as you appreciate the breadth of human experience and approaches to understanding the world around us.

The best software developers I’ve worked with have a broad range of interests outside of the field, and being well read is a consistent theme. Broaden your horizons and read more books unrelated to software.


Let’s say we’re testing a conditional rule that has three parts. The method looks something like this:

def all_good?
    a == 1 && b == 2 && c == 3

There are technically 2^3 = 8 branches there, since each variable can take on a value that is or is not equal to the value specified, and allow the rest to vary. The naive approach may looks something like this:

context "when a = 1" do
  context "when b == 2" do
    context "when c == 3" do
    context "when c != 3" do
  context "when b != 2" do
    context "when c == 3" do
    context "when c != 3" do
context "when a != 1" do
  context "when b == 2" do
    context "when c == 3" do

This is obviously absurd but sometimes while we’re testing, we get 3 levels deep into a conditional and don’t recognize that we’re actually repeating this pattern. It’s much less obvious to spot with real world code. 

Here’s a shortcut: all you have to do is test the case when all the conditions are satisfied, and then provide a single context for each sub-condition to prove that when it’s not met, the entire rule fails:

context "when all conditions are met" do
    let(:a) { 1 }
    let(:b) { 2 }
    let(:c) { 3 }
    it { should be_all_good }    
    context "when a != 1" do
        let(:a) { 99 }
        it { should_not be_all_good }
    context "when b != 1" do
        let(:b) { 99 }
        it { should_not be_all_good }

From 8 conditionals, down to 4. That’s pretty good! And much more readable, without all that nesting. If you had 4 pieces to the conditional, you go from 16 branches to only 5.

Happy testing!


I’m a framework geek. I love it when someone takes complex ideas and distills them into simple, visual structure. So when Eric Ries’s Lean Startup book came out a couple years ago, packed to the gills with simple frameworks, I was like: This is my jam. I want to work with people who think like this.

I started designing for startups shortly after that and eventually made my way, where I’ve had the opportunity to put some of the lean startup principles into practice.

Since reading Eric’s book I’ve bought all the other lean startup books, read all the blog posts, and downloaded all the slide decks filled with tips. And so I was downright giddy when Eric became an investor in Reverb this past fall and invited us to the lean startup conference. Do you see a pattern here? I’m a compulsive framework collector. I’ve been slow to share my own lessons learned though. So here’s my first cut at that, and my first cut at writing words on the internet that are not part of a UI design.

I’m going to create a series of these based on what we’re doing at Reverb called Frameworks FTW. Here goes.

Principle 1.
If you’re not focused on the speed at which you learn, then you’re doing it wrong.

Lots of people think startup success is all about speed. Ship code. SHIP code. SHIP CODE. It’s definitely about speed, but the speed you should be focusing on is the speed at which your organization learns.

Dan Milstein from Hut 8 Labs gave an excellent talk on this idea at the conference. Here’s his clever “math” for why creating an information-seeking organization matters. Hang on to your hats. I’m about to go 9th-grade geometry on you here and format this like proof. Admittedly, I may have gone a bit overboard.

Lesson Learned:
The rate at which you gather information + make decisions serves as a proxy for the speed at which you’ll generate revenue. The faster you learn what works, the faster you’ll make money.

Ok yes, ACTUAL revenue is measured in dollars. But you only make dollars if people are buying your product. And people don’t buy your product if you haven’t gained an understanding of how to make it work for them.

Do you remember the oft-repeated lean startup maxim “get out of the building”??? All that geek-math above illustrates why it matters.

It’s not enough to do this once or twice. You have to create a culture that values learning in this way so you sustainably ship meaningful features and products. Your engineers don’t like talking to customers? That’s a problem. Your designers don’t watch people use their designs? That’s a problem.

At the lean startup conference, I learned how creates space for engineers and designers to quickly see how customers react to their ideas. They recruit people to come in for UX and concept testing before they even know what they’re going to test!?! People come in for these sessions 5 days a week! Moderators walk the participant through a prototype while engineers and designers watch/listen via video and screen sharing. If they have a question for the researcher to ask the participant, they live chat it to them right in the moment. They flip “get out of the building” on its head and bring the people to their office, creating a constant stream of insights. Here’s the simple visual for this:

Lesson Learned:
Reduce the amount time between someone on your team wondering how customers will use your product and knowing how they will use it.

Bonus Tip: If you don’t have the resources to recruit and bring research participants to your workplace: Go here, plug in a url, and get a free five minute video of someone using your product: I’m told you can do three of those per month.

At Reverb, we don’t have the resources to do what Meetup does. However, we do have a small team almost entirely composed of the exact target audience for our product, and we’re co-located with the biggest user of our platform. So when the product team needs to understand how someone might interact with a new design, we can walk across the room or down the hall and put it in front of someone, watch them interact with it, and start learning. And if something breaks, you can bet we hear about it almost immediately.

Lesson Learned:
Reduce the distance between you and your customers by hiring employees that use your product on a daily basis and locate your office near your customers.

Another way we gain valuable insight from customers is by using software to help us send personal follow up emails at key moments.

Some examples: A customer starts creating a listing on Reverb but stops short of publishing it to the marketplace — they get a follow up email asking them if they need any help finishing the listing. A few days after they join the site — they get an email welcoming them and asking for feedback. They joined and made 3 sales in a row — they get an encouraging note to keep selling and tips on how to become a better seller. Each of these interactions gives us a chance to make our business personal and make people feel like the valued customer that they are.

By distributing different follow up emails across the team, everyone has the opportunity to learn from customers. If every customer interaction goes through customer service, other team members lose touch with the problems experienced by customers. You rob your team of hearing about pain points and you rob your business of having many brains thinking about how to solve issues.

Lesson Learned:
Have every employee connect with customers in personal ways to distribute learning and get all team members thinking about how to solve problems.

That’s the first principle and a few lessons learned in the Frameworks FTW series. If you like simple visuals and want to catch all of the posts, follow this blog and follow me on twitter.

If you’re a front-end developer (especially if you’re a musician) you should come learn with us. Apply at


Two weeks ago I outlined a number of challenges faced by apprentice (or other first-time) developers. The very first of these hurdles is new concepts and code standards, my description of which is below:

…wrangling with philosophical concepts that are either completely foreign or understood only in theory…(e.g.) the Law of Demeter, command-query separation, separation of concerns, and other SOLID principles.”

Today I’d like to elaborate on this challenge and provide some advice for both new apprentices and their mentors on how philosophical code concepts can be best learned and understood.

For apprentices, I have three recommendations regarding immersion, repetition, and feedback. The first suggestion, immersion, is self-evident, but important enough to state explicitly:

In order to learn as efficiently as possible, you really have to study (and I mean this in the traditional sense of the word) programming concepts regularly. I like to take time at the beginning and end of my day to check any blog posts shared in HipChat or on Twitter. I also read regularly outside of work. Reverb’s dev team meets weekly to discuss programming literature over lunch, which helps supplement my regular self study with expert opinions and anecdotes. Overall, I make sure that I’m constantly engaging with the dev community to keep up with both historical and current programming concepts.

This segways naturally into the second recommendation I have, which can be distilled down to one word: repetition. In order to transform described concepts into engrained knowledge, you need to apply these theories to your code.

This is actually easier said than done when you are working on projects that you don’t choose yourself. I try to find one thing that speaks to me and keep that in the forefront of my mind for a couple days. It’s only after implementing written rules in your own code that it truly begins to become second nature. For this reason, be aware that (depending on the concept) it may take a while before you can find a place to implement a particular strategy. I encourage you to bookmark articles to revisit them later and take notes when reading books so you have something to review in a couple weeks. Reviewing past literature will help you gauge your progress; an important part of growing from apprentice to journeyman.

The last suggestion I have regards feedback. While studying and applying new concepts and code standards to your work, it is easy to become isolated from the most important aspect of your growth: personal feedback. Open yourself to criticism; it is the best catalyst for learning. If possible, discuss your takeaways regularly with colleagues. Not only will this challenge your interpretations of your reading, it will also reinforce what you’ve read and help you adapt new concepts to your style of programming.

On the flip side, assisting mentors as they learn high level concepts can be a challenge. Too little help and an apprentice may develop incorrect practices or standards that aren’t aligned with the rest of the team. Too much information, however, can overwhelm an apprentice and impede the rate at which they learn. Mentors need to allow for appropriate pacing; rushing through literature for volume doesn’t allow for the knowledge to ‘sink in’. Encourage your apprentice to read and, if possible, read along with them and discuss the described concepts together. This will help you keep tabs on the apprentice and make sure they don’t wander astray.

That said, be patient. Expect repeated mistakes. It’s difficult to juggle multiple concepts at once when all are foreign. Try to focus on one area per week in order to make learning manageable. When critiquing code, address the area of focus as much as possible. This will help the apprentice learn by doing, but keep the criticism poignant enough that they don’t feel overwhelmed.

Finally, engage in empathy. This is universally important, but when dealing with an apprentice, its relevance is tantamount. Criticism is extremely helpful, but make sure your feedback is specific, actionable, and kind.

Welp this turned out to be far longer than I intended originally. Stay tuned for my next post, which will focus on improving tech-specific knowledge and the difficulty this might give a first-time developer.


Ten weeks ago I graduated from an intensive programming course called Dev Bootcamp and three weeks ago I began working for Reverb as their first apprentice web developer.

Being new to both my company and my profession, I’m in a uniquely challenging position that most experience only a few times in their lives. To start, there are hurdles that all developers face upon joining a new company. These include:

  • Familiarizing yourself with organizational conventions (e.g. for naming, file/folder structure, styling)

  • Codebase format, connectivity, and tools (eg libraries, deployment practices, proprietary scripts)

  • Company culture and chain-of-command

  • Company policies (e.g. hours, meetings, lunch)

Most professional developers are mindful of the chaos that comes from beginning a new job, but sometimes it may be hard to recall the complexity of acclimating to code as a career. There are several obstacles unique to newbie developers. Some examples:

  • New concepts and code standards

First-time developers are likely wrangling with philosophical concepts that are either completely foreign or understood only in theory. I’m talking about the Law of Demeter, command-query separation, separation of concerns, and other SOLID principles.

  • Improving tech-specific knowledge and comfort

There are going to be a lot of tools and methods with which new programmers are unfamiliar or not as capable as necessary. For instance, I’ve spent a significant portion of my first three weeks improving my understanding of test-driven development using mocks, stubs, and libraries that aid in this process (e.g. VCR for API calls).

  • Reverb-specific: VIM!!!

This is self-explanatory, but switching to Vim from TextMate and Sublime Text is an often frustrating experience that slows development significantly (although I’m already beginning to realize the long-term payoff).

Over the next couple weeks I hope to elaborate on both the stresses sourced from these challenges and how I’ve managed (or failed to manage) them. My hope is that by exposing my ignorance and detailing my journey from apprentice to journeyman, I can inspire others wandering a similar path and assist mentors in training and empathizing with their mentees.

-Joe Levering, Apprentice Web Developer @

blog comments powered by Disqus
Crafted in Chicago