A Hack On The Good Life2018-03-18T13:41:31+00:00http://ericfarkas.comEric FarkasWorking On Large Features2017-07-07T00:00:00+00:00http://ericfarkas.com/posts/working-on-large-featuresI’ve spent most of the last 18 months working on large features at my day job. For my purposes, a “large feature” will have most of the following characteristics:

Needs more than one developer, if the goal is to ship the feature in a reasonable timeframe (a month, a quarter, etc.).

Immediately becomes a core aspect of the product offering, from a business perspective.

Immediately becomes a core aspect of the application, from a developer perspective. An example of this would be doing a major version upgrade of Rails. Another is switching to a new background processing library.

Involves changes to core aspects of the application's data model.

Involves changes to core aspects of the application's business logic. A bug here would have negative business impact on customers.

If extending an existing feature, then making significant UI changes. This involves bringing in a UI/UX-focused team member.

Lots of new code, either reworking existing classes or introducing new ones. LOC is not a great measurement of the impact of a feature. Indeed, it's possible to leverage a small code change into a big win. But most large features that need more than one developer are also going to add a lot of new code.

Here are some things I’ve learned that have helped the teams I’ve been on to stay organized and ship large projects.

Plan Up-front

The worst thing to do when working on a large project is to start coding immediately. Resist the urge to spike. Instead, spend time planning what you will work on.

This will always involve a bit of guesswork. Many times, you will be working with incomplete requirements. You won’t have all the resources you need. And, of course, things change once people start using the actual feature.

What you’re trying to do is articulate what you do know, and how you’ll go about executing on it. I recommend using a tool like Trello to make cards for each distinct task. Even if you are not sure of all that the task entails, write it down.

Doing this accomplishes two things. One, it frees you from having to keep the entire feature in your head. Since you are working with other developers, this is a good thing. Second, it teases out the things you don’t know about the feature. You can then bring those questions to the right people. I create a “Questions” list in Trello for these issues, and ping the people who can help resolve them. In the meantime, I can work on what I do know.

Ship Early

As people a lot smarter than I haveargued, long-running feature branches can be painful. But sometimes you can’t avoid them. What I look for in the up-front planning phase are opportunities to get code into master as soon as possible. This way, if we do need a long-running feature branch, it will be as small and easy to review as possible.

With enough planning, database migrations are good candidates for early merging. Code refactoring that makes a path for new behavior is also a good candidate. For a recent feature, we shipped a refactoring of core business logic to production a month before the rest of the feature. In this way, we proved that the changes introduced in the new feature would be “backwards compatible”. It gave the rest of the team a comfort level with the new feature that they would have otherwise not have had. Other candidates are UI changes that are behind a feature flag, and new API endpoints that are not public yet.

An added benefit of going to master as soon as possible with smaller code changes is that team members not working on the feature need less context to review pull requests. Huge pull requests are hard to review, and often become a matter of “if it works, ship it!”. Smaller PRs are easier to review. Teammates don’t need to know the entire scope of the feature to review the change.

The faster you can get into master and deployed to production, the faster non-dev feature stakeholders can start using the feature. Again, I am standing on the shoulders of giants when I say this: the faster you can get to the point where you’re getting real user feedback, the better. My own experience has borne this out.

What I have found is that the more I try to ship things earlier, the better I get at identifying what to ship earlier. There doesn’t seem to be a hard and fast rule here. You’re going to need to experiment. I imagine much of your success in this area will depend on team culture and operational setup.

Keep Everything Green

If you are going to use a feature branch, treat it like master: keep it green all the time. Pull requests into the feature branch should be green themselves. If the feature branch’s tests are failing after a merge, stop what you’re doing and fix them.

It’s a nightmare to fix failing specs on a branch that has had a lot of churn. It feels like trying to hit a moving target. The sooner you fix failing tests, the better.

Double Down On Strengths

In chapter 12 of the 1950 edition of The Armed Forces Officer, entitled “Group Nature”, S.L.A. Marshall offers the following:

Progress comes of making the most of strengths rather than looking for ways to repair weaknesses. This is true in things both large and small.

Marshall was speaking in a military context. The stakes there are much higher than shipping software. But the thought is an intriguing one. I’ve come to understand that quote to mean this: when it comes time for battle, double down on your strengths. The time for self improvement, as an individual or as a group, is not on the battleground. You will learn on the battleground, but that’s not your main purpose.

Applying that idea to teams doing software development requires a delicate balance. Developers always want to work with new things and learn. But when working on large features that have business-impacting scope, the idea seems to be that developers should work on tasks that cater to their strengths.

This is not to say that developers shouldn’t have opportunity to work with new tech. Say you have two developers on a project. They both know Rails well. One knows React well, and enjoys front-end work. One has less React knowledge, and enjoys back-end and API work. They should work on what they are best at and enjoy the most. It doesn’t mean the developer who is front-end focused on this feature can’t work on the back-end, and vice versa. There will be plenty of smaller tasks that are perfect to learn on. But I would argue the bulk of the work each developer does should be in the area they are strongest in. Not all, but most. In this way, morale will stay high, since both developers are doing what they enjoy. Additionally, output stays high, since both are doing what they are comfortable with.

This isn’t a hard and fast rule. Sometimes both developers are good in the same area, and weak in the same area. The work will then be more evenly distributed. Team dynamics will always be at play here. In an environment with a lot of pairing, there will be more cross-pollination of learning. But even without pairing, learning can happen via pull request review as well.

The general idea is to play to your team’s strengths.

Stay Organized

Process for process sake is a waste of time. Process that gets in the way of shipping code is useless too. But process also gives structure to your work. The constraints of process provide the freedom within which one can stay focused on the task at hand.

We work hard to keep our Trello board up-to-date. If you are working on a card, assign it to yourself and move it to the “Doing” column. Move it to “Done” after merging the pull request. If there’s a discussion going on in Slack which results in a new task, put it in Trello. Keep checklists.

Doing these things allow us to actually focus on writing code. I don’t need to worry about remembering that thing we were talking about on standup because I created a card for it. I don’t need to remember what I am working on next. There are cards already assigned to me, or I can grab the next one from the “To Do” list. If a manager asks me about the status of the project, a glance at Trello will give them all the information they need.

The actual tool you use to organize is not as important as the fact of staying organized. I cannot stress enough how important it is to have an up-to-date task list that is accessible by any team member. I’ve never regretted taking the time to create and maintain such a list.

Summary

I am still learning about this part of the craft of software development. There’s still more to learn. But in the meantime, these are some of the things that have helped the teams I’ve been on ship features.

]]>A Refactoring Story2016-11-15T00:00:00+00:00http://ericfarkas.com/posts/a-refactoring-story
Last spring, development started up again on a side business that I'm
involved in. I'd hardly touched the two apps that run the business in over 3
years, and they needed some love. Back in May I discussed wrestling with the question of whether to Refactor or Rewrite these
apps. I decided to refactor, and I don't regret the decision.
What follows is one small refactoring that I did.

Context

TalentSoup is a marketplace.
It connects professional and amateur actors, actresses, and models
with producers and photographers. Talent sign up, upload photos, and
fill out a basic profile. They are then matched with
open projects in their area that they are a fit for.

Each talent sees a Talent Dashboard when they first log in. The Dashboard has two main
components. The first is a listing of all open projects across TalentSoup. The second,
a listing of projects for which they are under consideration to be cast.

The data driving these two components comes from a separate, internal
project management app we've written. This app exposes a REST-ful API
that TalentSoup calls to get the data it needs to display the
Dashboard.

Dashboard Behavior: How It Should Work

If it's the user's first time seeing the Dashboard, we want to display a "welcome message" which has
tips on how to get the most out of their TalentSoup account. There are
two cases which are a "first-time view" of the Dashboard. The first is a
new user signing up and being immediately redirected to the Dashboard. The second case is an
existing user who is viewing the Dashboard for the first time after we
had made significant UI changes to the old Dashboard. We want them to
see the "welcome message" too, since the changes were so radical. On subsequent visits,
they'll all see the real dashboard.

To keep track of whether a user had viewed the "welcome message", I
added a boolean column, wc_view, (default
false) to the users table (wc stands for
"Webcomp", which is what we call Talent portfolios). When the welcome message has
been viewed, wc_view becomes true. Looking
back, this column is unhelpfully named. Something like
welcome_message_viewed would have been clearer.

Initial Code

Before the refactor, the controller action driving the Dashboard code looked liked this (URLs are not real,
obviously):

Code Review

I cringe looking at this, but it's how I wrote code 4-5 years ago. You have to start somewhere.

If I were reviewing this code in a pull request today, I would make the following comments:

The dashboard action is not a REST-ful route, according to Rails idioms. It should extracted to it's own controller .

The controller is updating current_talent (an ActiveRecord object) directly. This means it has to know which columns mean what. The knowledge about how the application should determine whether or not a Talent has viewed the "welcome message" should be pushed down to the Talent class itself (or some other class?), but shouldn't live in the controller.

The knowledge about how to mark a talent as having viewing the "welcome message" should also live in the Talent class
itself (or another class), but not in the controller.

The two HTTParty calls to the external Commissary service means the controller
knows everything about where the endpoints are, and what to do in case of an error. This isn't the worst approach, but could be improved by moving these calls to a separate class. Doing so would also give us the benefit of being able to use those classes in other places.

Generally speaking, this code violates a number of rules that I (now)
try to abide by:

Violates Rails idioms.

Spreads too much knowledge about implementation details.

Misses the opportunity to extract interesting functionality
(calls to the external Commissary service) into small classes that can
be reused.

Is ugly to look at.

The Refactor

The first thing I did was move all the "has Talent viewed their
welcome message before?" logic out of the controller. I can get around
how badly the wc_view column is named by wrapping it in an
intention-revealing method.

# app/models/talent.rbclassTalent<ActiveRecord::Basedeffirst_webcomp_view?!wc_viewenddeffirst_webcomp_viewedupdate_column(:wc_view,true)endend# test/models/talent_test.rbclassTalentTest<ActiveSupport::TestCasedefsetup@talent=talents(:luke_skywalker)endtest"#first_webcomp_view? is true when wc_view is true"do@talent.update_column(:wc_view,true)assert@talent.wc_viewrefute@talent.first_webcomp_view?endtest"#first_webcomp_view? is true when wc_view is false"do@talent.update_column(:wc_view,false)refute@talent.wc_viewassert@talent.first_webcomp_view?endtest"#first_webcomp_viewed sets wc_view to true"do@talent.update_column(:wc_view,false)@talent.first_webcomp_viewed!assert@talent.wc_viewrefute@talent.first_webcomp_view?endend

Now I am able to clean the controller up, and rework the logic with
my new methods. The controller will be a bit easier to read, and the
implementation details have been effectively hid:

Now, the details about what columns Talent has, and what they mean,
are pushed down into the Talent class itself. If those columns change,
or if what it means to have made the initial view of your Dashboard changes,
we can change the underlying implementation and are less likely to need
to touch the controller.

Next, I re-worked the two calls to the external Commissary service.
I'm going to detail the "open projects" path, since it's shorter.

This is a simple class, but there's more going on that might initially appear. The
first is that there's an attr_accessor for an http_client. You
can't initialize the class with a custom http_client (the "default" is
HTTParty), but you can set one after initialization. I can't take credit
for this pattern; I learned it (and many other things!) from
Brandon Hilkert. The
motiviation for using this pattern will become apparent in the test
below.

I also convert the response into an array of OpenStruct
objects. This is purely for the convenience of using dot notation in
my views.

One of the advantages of this approach is that it makes the
Commissary::OpenProjects class easier to test. There are of
course many ways to stub/mock out an HTTP request, but using this
method, we don't need any external libraries! We can do it all in plain
Ruby:

require'test_helper'classCommissary::OpenProjectsTest<ActiveSupport::TestCasetest"#fetch with a good response"doclient=Commissary::OpenProjects.newclient.http_client=FakeHTTPartyopen_projects=client.fetchassert_equal1,open_projects.countproject=open_projects.firstassert_equal"987654321",project.idassert_equal"An amazing project",project.name# other assertions omitted for brevityendtest"#fetch when an exception occurs"doclient=Commissary::OpenProjects.newclient.http_client=FakeHTTPartyWithExceptionopen_projects=client.fetchassert_equal[],open_projectsendclassFakeHTTPartydefself.get(*args)[{id: "987654321",name: "An amazing project",}]endendclassFakeHTTPartyWithExceptiondefself.get(*args)raise"Oops!"endendend

We've "mocked" an HTTP request to an external service without using
a gem like VCR or Webmock. The disadvantage to this
approach is that, if the response from the Commissary service changes, I
can't just blow away my cassettes, as I could if I were using VCR, regenerate them, and fix my
tests. I'll have to fix my fake client(s) also. However, weighed against the
overhead of adding another gem to my app, it's a tradeoff I am willing
to make. Additionally, in writing a simple mock HTTP client like this,
you become familiar with the shape of the response coming back from the
external service in a way you don't when using VCR, for example.
That's been my experience, having used VCR extensively.

The other interesting thing in Commissary::OpenProjects
is the fetch class method, which is just:

defself.fetchself.new.fetchend

This is a pattern I learned from Michael Klett. It
can be more work than it's worth sometimes, but in this case, since the constructor for
Commissary::OpenProjects takes no args, having this class method saves us from doing
Commissary::OpenProjects.new.fetch, which I find aesthetically objectionable!

The motivation here is to adhere to Rails idioms. Additionally,
smaller controllers are easier to read, and therefore easier to get context
about. I don't mind an app with a lot of small controllers that do one
or two things well.

Conclusion

This code could be improved even further by extracting the methods on
the Talent class into a plain Ruby object (a "service"
object, in the parlance of our times). I decided against this because
the Talent class, although it represents the main user of
the app, is not a god object.
If, in the future, it feels like Talent is growing out of
control, I could see the value in such an extraction.

]]>Understanding updateIn & keyPath in ImmutableJS2016-08-10T00:00:00+00:00http://ericfarkas.com/posts/understanding-keypath-in-immutablejsImmutableJS is
a neat library, especially when used in combination with Redux. I’m not ashamed to
admit, though, that I found the docs confusing at first. For example,
look at the method signature for Map#updateIn():

updateIn() is a useful function to use when you’re interacting with Redux. I had to understand it. In the end, what helped me become productive with updateIn() was understanding the keyPath parameter.

The key (sorry) to understanding keyPath is to realize it’s just an
array of values that Immutable will call get with as it works it’s way through whatever data
structure you’re calling updateIn() on. It doesn’t matter if the value is a Map key or a List index. This works because both Map#get
and List#get inherit from Iterable#get
(https://facebook.github.io/immutable-js/docs/#/Iterable/get).

Consider the following data structure, which is a Map of endpoints, keyed on their id. The values are a List of Maps that represent that endpoint’s “subscriptions” to a
given event (enabled: true|false):

Now that we know how to construct a keyPath to any point in a deeply
nested data structure, we can move to understanding the updater parameter of updateIn.

The simplest way to understand updater is that it’s a function
that will be passed as it’s parameter the result of calling get on the
final element in the keyPath array. It should return the new value for
that…value. It’s easier to show in code.

Let’s say I wanted to flip the enabled flag for the subscription
represented by element 0 for endpoint abc-123:

endpoints.updateIn(["abc-123",0,'enabled'],isEnabled=>!isEnabled);

In the above example, I constructed the keyPath right down to the
enabled flag (the first parameter), and the second parameter is a
function that will be passed the current value of enabled as a parameter called isEnabled, and will simply return opposite boolean value of isEnabled.

You could back the keyPath up one level, as ["abc-123", 0], which
would give you the entire subscription Map at that index, and then
return a new Map with the enabled flag flipped. But in my
(limited) experience, I’ve not updated more than one attribute of a
given object at a time in a reducer. Hope this helps!

Listen...people be askin' me all the time,
"Yo Mos, what's gettin' ready to happen with Hip-Hop?"
Where do you think Hip-Hop is goin'?
I tell em, "You know what's gonna happen with Hip-Hop?
Whatever's happening with us."
If we smoked out, Hip-Hop is gonna be smoked out
If we doin alright, Hip-Hop is gonna be doin' alright
People talk about Hip-Hop like it's some giant livin' in the hillside
comin' down to visit the townspeople
We are Hip-Hop
Me, you, everybody, we are Hip-Hop
So Hip-Hop is goin' where we goin'
So the next time you ask yourself where Hip-Hop is goin
ask yourself: "Where am I goin'? How am I doin'?"

The "Rails is dead" meme has been around for a few years, and
it's been picking up steam again recently. Even among those who still
profess their love for Rails, it seems like some aren't excited about
Rails 5. One recent post even imagines what a Rails 6 that recaptures
the imagination would be like.

I make a living working with Rails, so this discussion interests me on a
personal level. What does the future hold for Rails? With frameworks like Phoenix gaining in mindshare, is Rails
finally dead?

What these discussions leave out is the fact that we are Rails. Rails will die when we stop using it. To put it another way:
Rails will stay alive as long as we continue to choose it for
projects.

There's isn't an official "Language and Framework Committee" that
decides which technologies are dead. Our small choices, when aggregated,
determine the fate of technologies.

So is Rails dead? I don't know. It's not dead for me: I love Rails and will continue to use it. But the larger point is that no one gets to tell you that Rails is dead; you need to decide that for
yourself.

Relevant Links

]]>Things I Learned This Week: May 16-20, 20162016-05-20T00:00:00+00:00http://ericfarkas.com/posts/things-i-learned-this-week-may-16-20-2016Dash
This app is already indispensable to my workflow. Just check it out.

Monotonic functions
A function is called monotonic if and only if it is either entirely increasing or decreasing.

Stateless Components in ReactJS
Stateless components are pure functions of their props. They (obviously)
don't have internal state, and do not call any component lifecycle
methods.

Ecto.Query.order_by/3
Learned various ways this function can be used. The Ecto version of
Rails' order("created_at desc") would be
order_by(desc: :created_at).

Ecto.Changeset.foreign_key_constraint/3Ecto provides the ability to capture foreign key constraint violations as errors on a changeset. The big difference to me between this function and assoc_constraint is that you can pass any key as the first argument, and Ecto will put the error on that key if the constraint fails. This is in contrast to assoc_constraint, which inflects on the key you pass in to determine what association constraint it's checking:

# Assume a post belongs to an author, lets ensure the author exists. If this fails,# the error will be put on the "author" key in the changesetassoc_constraint(:author)# We can also capture some other foreign key violation,# and put it on another key within the changesetforeign_key_constraint(:some_custom_changeset_key,name::some_database_fkey,message:"bad data!")

]]>New Podcast2016-02-23T00:00:00+00:00http://ericfarkas.com/posts/new-podcastI've started a podcast on briefs.fm, entitled Between Two Infinites.
The subject matter will be a mix of software development, philosophy, theology, and soccer.
]]>10 Things I Wish I Knew As A Junior Developer2016-01-15T00:00:00+00:00http://ericfarkas.com/posts/10-things-i-wish-i-knew-as-a-jr-devHere are some things I wish I knew when I was a junior (and solo) developer trying to "level up":

The best way to level up is by pairing with someone more experienced. Books & screencasts are great and should be used, but pairing will help you make the leap more quickly. My "level up hierarchy" is pairing > code review > books/screencasts.

Everything is a tradeoff. You need to see the advantages and
disadvantages of different approaches to solving a problem, and then
decide with your team which advantages are most important, and which
disadvantages you can live with. There will rarely be a perfect solution
to a problem, and the framework for deciding which tradeoffs to make
varies from team to team.

Design will become an important question. When you see two
classes with similar functionality, should you extract a common base
class? Should you move some methods to a shared module? Why or why not?
Your answers to these questions will change over time, but it's
important to develop reasoned opinions. Remember, everything is a
tradeoff.

One of the biggest challenges of working on a large Rails app is code
organization. Questions like "where do non-ActiveRecord classes go?" arise and are trickier to answer than they first appear.

There's nothing magical about the code you write for a large
app. There's no secret subset of Ruby (or Rails) that you need to be
initiated into before you can code "at scale". You will find yourself
considering different things when working on a large vs small app
(performance, background jobs, caching, etc.) but those are design issues. Ruby is still
Ruby.

Learn to love testing. In most cases, you should be nervous about shipping
code that is not tested.

Don't be afraid to ask questions of more senior developers if
something doesn't make sense. You'll either learn something new, or your
questioning will result in a new approach that the other developer
hadn't considered. Everyone wins!

If an idea doesn't make sense at the time, come back to it in 6
months. Sometimes we're not ready to absorb a new language or
paradigm, but that doesn't mean we won't be ready at some future point
after growing in another area. I had this experience with functional
programming.

Related to the last point, and somewhat contradictory, you need to aggressively find ways
to use new things. The only way to truly learn a new language or
technology is to build something with it. This will often require tinkering with
things on your own time. Some things are hard to learn, and require
persistence.

]]>Enjoy Yourself2015-09-25T00:00:00+00:00http://ericfarkas.com/posts/enjoy-yourselfI have observed a rather unsettling habit in myself: no sooner do
I achieve a goal, or acquire something I have been working towards,
than I begin to worry about losing what I have just acquired.

This feeling is not entirely out of place. After all, if we value our own time and energy enough to spend it in pursuit of some end, it
naturally follows that what was achieved is worth holding on to.

But I've noticed a tendency to let this "good anxiety" get out of
control. It slowly builds until I can't relax anymore.

What I've realized is that much of my happiness, "our" happiness,
is a function of making a conscious choice to responsibly ignore
worrying about the future. Worrying about the future is useful
inasmuch as it results in responsibly planning for the future.
For example, heart disease runs in my family. My father was only a few
years older than I am now when he needed emergency surgery for an
artery blockage. I do worry about that happening to me, and because of
that worry I've made exercising and eating (mostly) healthy a priority.

Similarly, worrying about financing college for your kids, or your
own retirement, is a good reason to save money now. But there comes a point where I accept the fact that I've done, or am doing, all that's in my power. There are things I cannot control, and I can't worry about those things. I will work as hard as I can, exercise, eat well, save money, etc., but I can't control the economy, or my own genetics. So why worry?

When I stop worrying about losing what I have, and instead focus on
enjoying what I have while it lasts, I find that I am able to conquer
anxiety and truly live "in the moment."

]]>Remote Work2015-07-08T00:00:00+00:00http://ericfarkas.com/posts/remote-workThis was posted in Slack a few days ago:

Any of the remote folks here have any resources on [building an ideal desk/office // stepping up the communication & collaboration game // building life structure] around remote work?

I'm coming up on 2 years at Chargify (and therefore 2 years of
full-time remote work), which puts me in a good position to share my experiences as they relate to the above questions.

Building An Ideal Desk/Office

My wife and I have four children, and we homeschool, so the house is full all day, everyday. My response is therefore affected by the fact that my house is a hive of activity.

The goal here is to have a space where you can work undistracted. To me that means you'll want a proper office with a door that locks. The understanding among your family has to be that the office is your space to work. When the door is closed, it means no interruptions. The lock is for the times when people forget what the closed door means. And they will forget.

The other thing about a room dedicated to work is that it allows you
to mentally segment home life and work life. I don't always work in my
office when I'm home (more on that in a bit). But even so, I know when I
am done for the day, I leave my office and shut the door, and that's
that.

Working from home gives you the unique opportunity to completely
customize your workspace. An ideal desk and office setup is relative to
what inspires you. What helps you focus and get "in the zone"? For
example, I like to have a view of the outside world when I work. I also try to
keep my desk free of non work-related things like bills and
mail. I find those sorts of things distracting. I'll get to the mail later; for now, I'm
working.

A view of the yard, and a clean desk

I recommend investing in a good pair of headphones or a headset. I use Sony MDRV6 Studio Monitor Headphones. I find that listening to music through headphones helps me focus more than listening through external speakers. YMMV. Here are two playlists I listen to when hacking:

I like to switch up my work location. I work in my
office 90% of the time, but sometimes I work in my living room, or at the local Starbucks, or even the pub!

Sometimes you need to put your feet up

Switching up work locations like this keeps me from getting into a
rut. Working remotely, I don't have face-to-face communication with
co-workers. I miss out on things like going with co-workers to a new place to get lunch, or grabbing a coffee mid-afternoon, things I was accustomed to when working in an office. Changing work
locations approximates this experience, however poorly.

Stepping Up Communication and Collaboration

The answer I'd give here would mostly be a summation of his thoughts anyway,
so I will just point you directly to Wynn Netherland's answer when I asked him the
same question.

I will add to that: communicate early, and often; don't be afraid to ask questions. The channels and means you use to communicate (synchronous vs. asynchronous) will be different based on the company, but the general principle applies. The worst thing in a remote job is to be stuck on something and feel alone. It doesn't have to be that way. Just ask!

Building Life Structure Around Remote Work

Working remotely has changed my life, and my family's life. We've
been able to travel for long periods of time, and as long as I have a
web connection (tethering FTW!), I can work a full-day and then have the
evenings and weekends to enjoy a new place.

I'd encourage anyone working remotely to try such a "work-cation". Of
course, it's easier for us to do because we homeschool as well, so we
can do school and I can work "on the road". That said, it can still be
done, you just need to be creative. When we travel we mostly stay with
family and friends to keep our costs down, but with Airbnb it's possible
to find long-term (1-2 month) rentals at an affordable cost.

Remote work presents a great opportunity to do interesting things,
but it's important to remember the work part of "remote work". In
everything you do (working at a coffeeshop, doing a "work-cation"), keep
in mind that you're part of a team, and the implicit understanding is
that you're responsible enough to be productive and manage yourself. The
goal is for everything you do to be transparent to your co-workers: no
matter where you're working or what your office looks like, you're still
contributing at a high level to your company. When my family travels out of
town on extended trips, we always drive on weekends or late at night, so
that I can still work a full day/week. If I want to take a day off to
do something fun with my family, I take it, but otherwise, it's a normal
work day, sitting poolside notwithstanding.

My desk for one month last year, at my in-law's in Florida

Additionally, I think it's important to have a routine when working
remotely. Have a consistent general start time, and general end time. Take a real
lunch break. It's easy to either a) work all the time, since you can
work anywhere, or b) become undisciplined in work habits because no one
is micromanaging you. You're conscientious, and responsible: don't let
that happen to you.

Use the fact that you don't have a commute to your advantage. Spend
the hour that would have been spent in the car or on the train instead on reading a technical
book, or exercising. I've recently started waking up around 6:30am,
making coffee, and just taking the morning easy by reading or going for
a run. The kids are still asleep during that time and I can get out in
front of the day instead of the day's events controlling me. When
working remotely it's easy to sleep until 10 minutes before you're
expected to be online, then rolling out of bed and starting work. Again,
you're not that kind of person; you're going to make the most out of the
the time you have.

Closing Thoughts

Remote work is fun, but also challenging. Unfortunately I've seen
people who can't handle the responsibility of working remotely. And
that's very sad to me, because it's such a great opportunity for so many
things. So communicate well, work hard, and enjoy yourself.

See Also

]]>Elixir and Phoenix Quickstart Guide2015-05-27T00:00:00+00:00http://ericfarkas.com/posts/elixir-and-phoenix-quickstart-guideI've begun tinkering with Elixir and the Phoenix framework. The guides on the Phoenix site seem to be slightly out of date, so I thought it'd be helpful to post a quick start guide. I am running OS X 10.10.3.

1 - Install Elixir via Homebrew

$ brew install elixir

The latest version as of today is `1.0.4`. Along with Elixir comes Mix.

Mix is a build tool that provides tasks for creating, compiling, testing Elixir projects, as well as handle dependencies, and more.

5 - Start the web server</h5>

$ cd phoenix_test_app
$ mix phoenix.server

]]>State of the Setup - Fall 2014 Edition2014-11-12T00:00:00+00:00http://ericfarkas.com/posts/state-of-the-setup-fall-2014-editionHere's a list of stuff I currently use everyday in the service of
personal and professional productivity:

]]>Inheritance2014-11-06T00:00:00+00:00http://ericfarkas.com/posts/inheritanceI'm coming to the opinion that, in Ruby, inheritance is never the first tool you should reach for when designing classes. This has been a difficult mental shift for me to make, coming to Ruby as I did from the Java world. Reading Practical Object-Oriented Design in Ruby earlier this year first put the idea in my head. But recent experience doing post-mortems on production code which made use of inheritance has made the abstract idea concrete.

The major reason for this shift in thinking is that, in my
experience, code which makes
use of inheritance is harder to reason about. This is especially the
case when one is trying to track down a bug during an outage or some
other "support incident". Your experience may be different. But there's
something to be said for having all the methods that a class makes use of all in one place.

It can be argued that composition also introduces the same type of
problem, but it's mitigated for me by the fact that classes
which make use of composition tend to have shallower hierarchies. Most
of the time you're just jumping to one file to look for a method
definition, whereas with inheritance you are potentially jumping into a
complex class hierarchy.

I'm beginning to think that dependency injection is the best way to
make potentially complex model interactions very simple. When you focus
on message-based design, you quickly discover news ways to leverage Ruby's
duck-typing capabilities in the service of writing small classes that do
one thing and are simple to reason about. These types of classes are
easy to change, and in my experience, easier for the person who didn't
write them to someone to come in and understand. And for teams working
on large applications, that's a big win.

Chapter 1 - Object Oriented Design

Single Responsibility Principle: a class should have only a single responsibility.

Open-Closed Principle: Software entities should be open for extension, but closed for modification (inherit instead of modifying existing classes).

Liskov Substitution: Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.

Interface Segregation: Many client-specific interfaces are better than one general-purpose interface.

Dependency Inversion: Depend upon Abstractions. Do not depend upon concretions.

Other principles include:

Do Not Repeat Yourself: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

Law of Demeter: A given object should assume as little as possible about the structure or properties of anything else.

Chapter 2 - Designing Classes with a Single Responsibility

A class should do the smallest possible useful thing.

Applications that are easy to change consist of classes that are easy to resue.

How can you determine if the Gear class contains behavior that belongs somewhere else? One way is to pretend that it’s sentient and to interrogate it. If you rephrase every one of it’s methods as a question, asking the question ought to make sense. For example, asking “Gear, what is your ratio?” seems perfectly reasonable…“Gear, what is your tire size?” is just downright ridiculous.

Chapter 3 - Managing Dependencies

An object depends on another object if, when one object changes, the other might be forced to change in turn.

Recognizing Dependencies

An object has a dependency when it knows:

The name of another class

The name of a message that it intends to send to someone other than `self` (methods on other objects).

The arguments that a message requires.

The order of those arguments.

Your design challenge is to manage dependencies so that each class has the fewest possible; a class should know just enough to do it’s job and not one thing more.

The more one class knows about another, the more tightly it is coupled.

Test-to-code over-coupling has the same consequence as code-to-code over-coupling.

Factory: an object whose purpose is to create other objects.

Depend on things that change less often than you do.

Some classes are more likely than others to have changes in requirements

Concrete classes are more likely to change than abstract
classes

Changing a class that has many dependents will result in widespread consequences

Abstraction in Ruby = duck typing; depending on an interface (objects will respond to methods) rather than a concrete class implementation.

Chapter 4 - Creating Flexible Interfaces

Domain objects are easy to find but they are not at the design center of your application. They are a trap for the unwary. If you fixate on domain objects you will tend to coerce behavior into them. Design experts notice domain objects without concentrating on them; they focus not on these objects but on the messages that pass between them.

Using a kitchen analogy: your objects should “order off a menu” instead of “cooking in the kitchen”.

This transition from class-based design to message-based design is a turning point in your design career. The message-based perspective yields more flexible applications than does the class-based perspective. Changing the fundamental design question from “I know I need this class, what should it do?” to “I need to send this message, who should respond to it?” is the first step in that direction.

Ask for “what” instead of telling “how”.

You don’t send messages because you have objects, you have objects because you send messages.

Context: the things that an object knows about other objects. Objects that have a simple context are easy to test, objects with a complicated context are more difficult to test.

The best possible situation is for an object to be completely independent of it’s context (dependency injection). I know what I want and I trust you to do your part.

Law of Demeter

Only talk to your immediate neighbors

It’s a “law” in the sense of a guideline, not a hard and fast rule.

Balance the likelihood and cost of change against the cost of removing the violation.

…Demeter is more subtle than it appears. It’s fixed rules are not an end in themselves; like every design principle, it exists in service of your overall goals. Certain “violations” of Demeter reduce your application’s flexibility and maintainability, while others make perfect sense.

The problem with Demeter violations (like customer.bicycle.wheel.rotate) is that they show that code (customer) knows too much about how other code works. It’s a manifestation of tight coupling.

The train wrecks of Demeter violations are clues that there are objects whose public interfaces are lacking.

Chapter 5 - Reducing Costs with Duck Typing

Duck types = public interfaces not tied to any specific class

It’s not what an object is that matters, it’s what it does.

Concrete code is easy to understand, but costly to extend. Abstract code may initially seem more obscure but, once understood, is far easier to change.

Once you begin to treat your objects as if they are defined by their behavior rather than by their class, you enter a new realm of expressive design.

Recognizing Hidden Ducks

Case statements that switch on class, kind_of?, is_a?, and responds_to? are potential ducks.

Chapter 6 - Acquiring Behavior Through Inheritance

Inheritance is, at it’s core, a mechanism for automatic message delegation. It defines a forward path for not-understood messages.

Chapter 7 - Sharing Role Behavior With Modules

Combining the qualities of two existing subclasses is something Ruby cannot do (multiple inheritance)

Because no design technique is free, creating the most cost-effective application requires making informed tradeoffs between the relative cost and likely benefits of alternatives

Classical inheritance vs module inclusion can be thought of as is a? vs behaves like.

Method Lookup Flow

Including a module inserts it's method "above" it's superclass, in the object hierarchy.

Therefore, if a method exists anywhere in the hierarchy between subclass and superclass, and also in an included module, the superclass method wins out.

When a single class includes several different modules, the modules are placed in the method lookup path in the reverse order of module inclusion. Thus, the methods of the last included module are encountered first in the lookup path.

Note: Sandi mentions that the above image could in some cases be more complicated, but for most programmers it’s ok to think of the object hierarchy in this way

Writing Inheritable Code

Recognize the antipatterns

Insist on the abstraction

Honor the contract (Liskov Substitution Principle)

Use the template method pattern

Preemptively decouple classes (avoid `super`)

Create shallow hierarchies

…when a sending object checks the class of a received object to determine what message to send, you have overlooked a duck type. This is another maintenance nightmare; the code must change everytime you introduce a new class of receiver. In this situation all of the possible receiving objects play a common role. They should be codified as a duck type and receivers should implement the duck type’s interface. Once they do, the original object can send one single message to every receiver, confident that because each receiver plays the role it will understand the common message.

Insist On The Abstraction

If you cannot correctly identify the abstraction there may not be one, and if no common abstraction exists then inheritance is not the solution to your design problem.

Create Shallow Hierarchies

Depth = number of superclasses between object and the top; breadth = number of it’s subclasses. Prefer shallow & narrow.

Inheritance gives you message delegation for free at the cost of maintaining a class hierarchy. Composition allows objects to have structural independence at the cost of explicit message delegation.

Composition contains far few built-in dependencies than inheritance; it is very often the best choice.

With inheritance, a correctly modeled hierarchy will give you the benefit of propogating changes in the base class to all subclasses. This can also be a disadvantage when the hierarchy is modeled incorrectly, as a dramatic change to the base class due to a change in requirements will break sub-classes. Inheritance = built-in dependencies.

Enormous, broad-reaching changes of behavior can be achieved with very small changes in code. This is true, for better or for worse, whether you come to regret it or not.

Avoid writing frameworks that require users of your code to subclass your objects in order to gain your behavior. Their application’s objects may already be arranged in a hierarchy; inheriting from your framework may not be possible.

Chapter 9 - Designing Cost-Effective Tests

3 Skills Needed to Write Changeable Code

Understand OO design

Skilled at [refactoring](http://refactoring.com/) code

Ability to write hig h-value tests

Changeability is the only design metric that matters; code that’s easy to change is well-designed.

Good design preserves maximum flexibility at minimum by putting off decisions at every opportunity, deferring commitments until more specific requirements arrive. When that day comes, refactoring is how you morph the current code structure into the one what will accommodate the new requirements.

Tests free you to refactor with impunity.

The true purpose of testing, just like the true purpose of design, is to reduce costs.

Intentional Testing

Benefits of testing

Finding bugs

Supplying documentation ("Tests provide the only reliable documentation of design.")

Most programmers write too many tests…One simple way to get better value from tests is to write fewer of them.

Dealing with objects as if they are only and exactly the messages to which they respond lets you design a changeable application, and it is your understanding of the importance of this perspective that allows you to create tests that provide maximum benefit at minimum cost.

Here, then, are guidelines for what to test: Incoming messages should be tested for the state they return. Outgoing command messages should be tested to ensure they get sent. Outgoing query messages should not be tested.

Knowing When to Test

First, obviously.

Tests are reuse.

Your application is improved by ruthlessly eliminating code that is not actively being used.

Freeing your imagination from an attachment to the class of the incoming object opens design and testing possibilities that are otherwise unavailable.

]]>My git Workflow2014-03-29T00:00:00+00:00http://ericfarkas.com/posts/my-git-workflowI've settled into what I think is an effectively simple git workflow that I thought would be helpful to share.

Let's say I am working on a new feature. First thing I want to do is
make sure my local copy of the codebase is up-to-date:

$ git pull master

I'll then create a new feature branch. In my experience, 99% of the
time I am branching off of master:

$ git checkout -b an-awesome-new-feature

But it’s just as easy to branch off another branch:

$ git checkout -b an-awesome-new-feature some-other-branch

Within this new branch, I can spike on the new feature, and if things
get hairy I can blow it away and start over. I'll commit often. Most of
my commits during the spike or early phase of a feature will look
like:

$ git commit -am "WIP specs"

If I am
pairing, I will be more descriptive with the commit messages. But when I am
coding alone, these pre-PR commits are for me, and are not meant to be
used for any meaningful code review. When I am satisfied that I the work I've done will eventually become a PR, I'll push my branch to a remote:

$ git pushr

The pushr command is a nice little shortcut from the dotfiles I use. It creates a remote branch with the same name as my local branch, in this case, an-awesome-new-feature. After the initial git pushr, I can just do git push and it will push to the remote branch.

The "do some work, test, commit, push" loop happens until I am
satisfied that the feature is ready for a pull request. If a new feature
was merged into master that will effect my feature, I'll
pull the changes in, and then do:

$ git rebase master

Recently I've gotten into the habit of rebasing my
feature branches whenever anything is merged into master,
even if I don't think they will effect what I am doing. I've done this
mainly because, if there is a conflict, I'd rather be in merge hell in
the middle of working on a feature than at the end of a feature. It's dispiriting when you're about to open a shiny new PR and you realize it won't merge cleanly.

At this point I
will rebase
and squash all of my commits on the
an-awesome-new-feature branch into one commit. This commit
message will be as informative (detailed) as possible, since it will become the
basis for the pull request message.

Once that's done, I'll force push to the branch with my new rebased
history:

$ git push --force

I'll then open my pull request. I will push new commits to the branch
after the PR is open, based on feedback. Once I get a :shipit:, I like
to re-squash all post-PR commits back into the first PR commit.

There's
been some discussion on our team about the merits and demerits of this
approach. I like to have one commit per PR when it's possible. It seems
cleaner to me. But there's a good argument for not doing this, since
those post-PR commits were changes made based on feedback, and that
feedback history is important to have. Personally, I feel the comments
in the PR on GitHub are sufficient as far as history goes. Usually if I
want to dig deeper into what went into a new feature and why, I'll go back and re-read
the PR message and subsequent comments, as opposed to reading commit messages in git log. But that's my
own preference. The other way is fine too, in my opinion.

In either case, once the PR is merged, the feature branch is deleted
locally and remotely. The master is updated locally via
git pull, and the cycle repeats.

Newton's first law of motion states that objects in motion
tend to stay in motion, and objects at rest tend to stay at rest, unless
acted on by an external force. This law explains the reason behind an
opinion I've adopted: starting something is difficult. Of course
finishing, and finishing well, are also difficult. But I think that
first leap, from doing nothing to something, is
harder.

Talk is cheap. It costs nothing to say you will do something. And people love to talk about the amazing plans they have. But
there's a price to putting forth an effort. Doing something
means not doing other things. It's a sacrifice of time, sometimes with
family, oftentimes of activities that are themselves enriching. Doing
something means there will an end product, which can be (and
often is) criticized. So there's also the emotional price which must be paid.

Additionally, you have those laws of motion working against you. It
seems to be our nature, that when we're doing nothing, we tend to
continue to do nothing. There's also some Lizard Brain stuff going on too. So to go from doing nothing to
something, an outside force is needed. As you mature you realize
that in many cases, you need to be your own outside force. You come
to understand that you're fighting against yourself to get stuff done.
A self-motivated person is one who understands that, and doesn't need
(or wait for) someone to give them a push.

If you're part of an organization, you can see this play out everytime you have some sort of housekeeping meeting. Ask for
feedback on an issue, watch the hands go up. Everyone likes to talk
about how things should change, what they would do if they were in
charge. Ask for volunteers to work on implementing that change, or watch the
follow-up effort by folks who just "do stuff", and it's usually
disappointing.

Therefore, I am one who praises effort, even effort that
results in something of low quality, because I appreciate how hard it is
to do something. Especially when that effort is the beginning of
something. When I see someone attempt to organize an event
and fail, ship a software product that I find ridiculous, start a
workout program, or many other things like that, I will always admire the
effort. At least they are trying. People who offer nothing other than words
shouldn't criticize the people actually doing something.

The only time effort itself should be criticized is if it's sub-par. One should always aim for excellence. But excellence is hard to achieve, especially at the beginning of a thing. So as long as someone is trying as best as they can, and working to improve, their effort should be praised.

Poor outcomes are tolerated on the way to better outcomes. Poor effort is never tolerated. Honest effort is always to be praised.

]]>Learning vim2014-01-28T00:00:00+00:00http://ericfarkas.com/posts/learning-vimI've spent the last 6 months all-in with vim. At Chargify, we use vim when doing remote pairing, so it's been necessary to get up to speed for that reason alone. To shorten the learning curve I uninstalled TextMate on my personal laptop and have been using vim for all TalentSoup development as well. My vim knowledge was basic when I joined Chargify, and while I am far from expert at this point, I am productive and learning more each day.

Given the experience of needing to go from 0 to productive in a short period, I'd offer that the best way to learn vim is with someone else. Whether you use someone's dotfiles (I use a fork of my colleague Jeremy Rowe's dotfiles) or not is a secondary concern. Nothing will speed up your vim education like having someone watch you attempt to do something, and suggest another, more efficient way. A great set of dotfiles is super helpful, but more important is that you have someone offering guidance.

More and more I am becoming convinced that the pairing model is the best way to get better at software development. If you can find someone to be a mentor to you, you're in a great spot.

P.S. - If you can't find someone to pair with to learn vim, I recommend watching the Destroy All Software
screencasts. You'll see Gary do a lot of crazy things, which will lead
you to ask "how did he do [X]", which will start you on the right
path.

]]>A Developer's Daily Checklist2013-10-23T00:00:00+00:00http://ericfarkas.com/posts/a-developers-daily-checklistBelow is a list I am going to read everyday before I start working. Some points are repetitive, because I need to hear them over and over. This list is in no particular order.

Communicate early, and often. Don't be afraid to ask questions.

If something isn't clear or a proposed solution doesn't seem right, say something. At best you've discovered a blind spot in your team's approach, at worst, you will have learned something. So you win either way.

Assume nothing. Take the extra time to confirm or refute your assumptions by asking a team member.

Program defensively. Assume users will break things and enter bad data, or that the worst will happen.

It's ok joke around and shoot the breeze every so often, but at the end of the day, this is your job. Be serious about it.

Every moment is a teachable moment. Learn, soak in as much as you can from others. Again, ask questions: "Why are you doing it that way? What does that method do? What are some others ways to do the same thing?" Pair programming offers so many opportunities for this interaction, which is why I think it's the best way to level up.

Understand that, even though every PR is reviewed by others, there's a level of trust in you as a developer. Own the code you write, and take pride in it. Make sure it works, don't assume others will catch a mistake.

Never. Stop. Learning.

Ask about blind spots: "What other parts of the app might break if I change this? What are some "gotchas" about the process I am working on that are perhaps not apparent? Can you just go over with me what's happening here?"

Document useful things you discover.

If something is broken, fix it.

The biggest takeaway for me, especially as a remote worker, is to just speak up if you have a question or are unsure about something. In my experience, colleagues are very understanding about getting someone up to speed with how the app works, or to just go back and forth talking about the merits and demerits of a particular approach.

]]>The Challenges Of Being A Solo Developer2013-07-24T00:00:00+00:00http://ericfarkas.com/posts/the-challenges-of-being-a-solo-developerSince October 2009 I have been the only developer at TalentSoup. In the past, I've been part of large co-located teams, and smaller distributed teams (across continents). TalentSoup is my first experience building an application this large, by myself. I want to briefly talk about my experience as a solo developer, and offer some helpful tips to others in the same situation.

In short, the best part of being a solo developer is that you can do whatever you want. Also, the worst part of being a solo developer is that you can do whatever you want.

The Best Part

The best part of being a solo developer is that you can do whatever you want. It turns out that this is a double edged sword, as I'll get to below. But there are times when it's nice to use whatever technologies or frameworks that you are most productive with. No bureaucracy to deal with.

The other great thing is that you learn a lot. When working on an application with other developers, the tendency is to divide up the work based on the expertise of the team, especially when time is of the essence. It takes a strong lead developer to say, "Jane doesn't have a lot of experience with billing systems, so we're going to let her spend the next few weeks working on some news features for ours, so she can learn." As a solo developer, you get those opportunities by default. For me, this also involved learning basic sysadmin stuff, like securing a new server, troubleshooing server issues, scaling up the application, things of that nature.

All this, in addition to all the little things you learn as you refactor, gain a deeper understanding of your language and framework, etc. Not to say I wouldn't have learned as much if I were working with someone else, just that I had to learn. Having worked in the past at places where there were separate teams handing server and database administration, I enjoyed the chance to dig in to new things.

The Worst Part

The worst part of being a solo developer is that you can do whatever you want. The longer I am a solo developer, the more I think it's a net negative. Unless you have an exhaustive knowledge of the technologies available for a given solution, and the experience to know the benefits/limitations of each, the fact is that you will have blindspots in your thinking. I'm not saying that someone with limited experience can't find a good solution to a problem. What I am saying is that it's good to have someone who can suggest a couple of different courses of action, because there might be a solution that fits your problem better than the one you're about to implement.

This principle also affects the learning process. There have been times when I have wanted to try out a new database for example, but knowing there'd be a learning curve, I avoided it and stuck with what I knew. There's a good business reason for doing this: when stuff breaks, it's better to be working with something you know how to fix. But it would have been nice to be working with someone who had experience with that new database and provided a safety net in terms of knowledge and experience. Even if no one on a team has experience with a new technology, stepping into the unknown with a group is better than stepping in alone.

Another factor is that we all have comfort zones. I have test frameworks and gems I like to use, and a development process that feels comfortable to me. But if I want to keep my skills relevant, thinking about opportunities beyond my current position, it would be in my best interest to branch out and learn other things. As a solo dev, unless you are really disciplined, it's hard to step out of that comfort zone.

Also, it can be emotionally difficult to bear the weight of knowing every feature, bug fix and upgrade depends on you. This can lead to burnout.

Finally, when you are a solo developer, there's no one to review your actual code. No one to call you out on a bad implementation, or educate you on the idiomatic way to do a certain thing. No one to raise a flag when untested code goes into production. I've gotten into some bad habits that have taken much effort to reverse. When you are a solo developer you don't get the positive peer pressure that's needed to grow as a craftsman.

A Way Forward

The challenges of being a solo developer aren't insurmountable. If you feel that you're not able to get out of your comfort zone, you have to, in the words of my friend Matt, "Aggressively find ways to use things." It takes being disciplined and intentional to gain experience with new things when you are on your own. There's no other way. No secret sauce.

I've had the privilege of getting to know some really good Ruby developers. I'll send an email every once in a while asking how they'd best solve some problem, or if they could recommend a book to help me level up. There are also resources like pairprogramwith.me if you're looking to pair with another developer. I got to spend a day pairing with a startup recently, and it was an eye-opening experience, one that I am eager to participate in again. Talking out loud with another developer, while looking at the same code in the same room, exposed so many areas of my craft that I need to improve. It was worth many books and screencasts.

If you are feeling overwhelmed by your workload, might I suggest something counterintuitive: walk away. Take a day or two and don't open the editor, or look at a bug list. Just take some time for yourself. Or, if you are going to work, work on a pet project, something fun. At TalentSoup, a couple of small features that have turned out to be popular were the result of me blowing off a laundry list of things I had to do, to work on something fun, just for my sanity.

These certainly aren't an exhaustive list of solutions, but if you're a solo dev and know you will be for the forseeable future, it's a starting point.

]]>Recent Experience With Service Objects In Rails2013-07-13T00:00:00+00:00http://ericfarkas.com/posts/recent-experience-with-service-objects-in-railsI read Bryan Helmkamp's blog post 7 Patterns to Refactor Fat ActiveRecord Models when it was originally posted, but it's taken me until recently to implement some of his suggestions in TalentSoup. Specifically, I've been writing service objects, using similar criteria to Bryan.

One quick example of how I've used service objects is in the downgrading process. Previously, my code for downgrading an account looked like this:

My user.rb class was responsible for post-downgrade cleanup in the downgrade_brand_to method, like canceling the subscription with Chargify, and resetting some of the features availabile to our Pro users. The code certainly worked, but there were a number of things wrong the approach (besides how obviously hideous it is!):

Spread out the business logic behind canceling across a controller and a model. I always want to log the reason for a cancellation along with doing the actual canceling, but the previous implementation had those two occuring separately.

Since there was no single point of entry that would encapsulate the entire downgrade process, it was hard to test.

It was also not portable. We might want to downgrade in other parts of the app too (reconciliation process via Rake task, perhaps) and the current process would necessitate repeating ourselves, and possibly leaving out something important.

To be quite honest, as great as those things are, the biggest win for me so far has been that I feel better about the application. I feel more confident going in to change things, because I can focus on much smaller parts of the application, rather than digging into God models. As a solo developer, it becomes harder to keep the whole application in your head as the code base grows. Therefore, anything that will express business logic in a concise way and make it easier to come back and understand months later ("I just need to look at one small class to see what we do when we downgrade") is huge.

See Also

]]>How To Create Opportunity2013-04-19T00:00:00+00:00http://ericfarkas.com/posts/how-to-create-opportunityA number of related but scattered thoughts on the subject of creating opportunity for yourself.

Favor Action Over Inaction

Look at goals you have in terms of actions to be taken. It's not enough to write down ideas and talk about them. You have to work to implement them. Recently someone at my church suggested regularly getting together during the summer at a local beach for volleyball. Everyone was enthusiastic about the idea. But to make it happen, someone needs to contact the town and see if we need a permit, and if we do, to work at getting that permit. Someone else needs to purchase equipment. There is action to be taken; who's going to take it?

I think it's helpful to see yourself as a hustler, and I mean that in the sporting sense. In baseball, someone who's a hustler will run out every ground ball, dive for every line drive, chase every ball hit anywhere in the outfield. At the end of the game, he comes back to the locker room with a dirty uniform. To a hustler, there are no lost causes.

The way this played out for me is that I spoke to everyone who wanted to work with me, everyone with an idea. I answered emails, met with people, even if I had an inclination that it would be a waste of time. Because you never know. Every potential opportunity is worth a look. This mindset (at the time I was looking for a project to be involved in long-term) is what caused me to answer a random tweet, which led me to Radford Harrell and TalentSoup. On the surface it looked like short-term work, but it turned into 3-1/2 years (and going!) of a great partnership. You never know.

The nature of the hustle will change over time. Now that I am in a situation that I worked hard for many years to find, the types of opportunities I am looking for has changed. I want to meet people who will help me grow my business, and help me improve as a developer, whereas before I was looking for a project to be a part of. But the bias toward action will always exist.

Sometimes It's Better To Stay The Course

All of that said, being biased towards action does not necessarily mean always looking for new things. If you're in a situation where you are really unsure of what to do, consider the possibility of just carrying on. But hopefully "carrying on" for you means continuing with some action, as opposed to doing nothing.

Remember The Sabbath

The Sabbath is a day of rest. Among it's practical benefits (naps for the whole family!), it also serves to remind us that the increase in our lives is not down to our own working. We are led to believe that working long hours and sacrificing time with family and loved ones is what it takes to be "successful". By allowing me to observe a day of rest from work, God is reminding me that ultimately, He is the One who provides for me. Yes I work hard, but every good thing in my life comes from God. The apostle Paul elaborates on this idea in the first letter to the church at Corinth:

What then is Apollos? What is Paul? Servants through whom you believed, as the Lord assigned to each. I planted, Apollos watered, but God gave the growth. So neither he who plants nor he who waters is anything, but only God who gives the growth.

In that context he's talking about his work in the ministry of the Gospel, but the principle is clear: ultimately God is the one who prospers (or does not prosper) the labor of His people. Much more can be said about this point and how it relates to contentment. It's enough for now to remember that while you are working hard, God is the one who is directing your life, opening and closing doors, and adding (or not adding) increase through your labors.

]]>Things To Look Out For When Building An App2013-04-02T00:00:00+00:00http://ericfarkas.com/posts/things-to-look-out-for-when-building-a-large-applicationA while back I found a great set of notes that were taken at a presentation by del.icio.us creator Joshua Schachter at the 2006 Future Of Web Apps summit. They were really helpful to me in my growth as a developer. Unfortunately the notes are no longer available at the original URL, so I've taken the liberty to reproduce them here.

Again, these are not my own notes (credit goes to Simon Willison) but I want to preserve them for posterity's sake. If you know of an "official" location for these notes please let me know.

Browser quirks. CSS/JavaScript/rendering. IE caching.

Scaling: avoid early optimization. SQL doesn't map well to these problems - think about how to split up data over multiple machines. Understand indexing strategies, profile every SQL statement. Nagios or similar for monitoring.

Tags don't map well to SQL. Sometimes you can prune based on usage - only index the first few pages for example. This keeps indexes small and fast.

Some latency in the system is OK - work out where you have leeway, e.g. RSS feeds can fall a few minutes behind without anyone minding.

People are always going to abuse your system (scraping, greasemonkey, etc.)

"Idiots are a lot smarter than you" - wait to see what breaks before you fix it.

Learn Apache - tuning can make things a lot faster. Understand headers, mod_rewrite (a dark art). Put a proxy in front of Apache e.g. Perlbal from LiveJournal - one guy on a modem can suck up lots of resources otherwise.

Images off a different server, RSS from a different server.

"Save site for offline use" feature in IE is particularly nasty.

The easier the API to get in and out of, the more people will use it. There's a long tail of smart developers. Stuff like SOAP discourages adoption. No API key = people can play with it faster; drives attention.

Don't expose your unique id's to the outside world (php?id=1 etc.) People can scrape through everything very easily. This is why del.icio.us uses MD5 hashes of links instead.

Giving everything a unique ID in the database is a scaling problem in its own right.

Features: the features you put in are as important as the ones you leave out. There's no "send a note" in del.icio.us feature because e-mail already exists.

I don't add featues that are available elsewhere e.g. messaging

When people ask for features, get to the bottom of why they are asking for that exact thing. Solve the problem, rather than doing exactly what your asked for.

With tags, people ask for "A and B and NOT C or D" - but less than 1% of queries even use more than a single tag.

RSS important in del.icio.us, because it's a native way for people to access lists (of links). Put RSS everywhere you can. del.icio.us does way more RSS traffic than HTML or API stuff - partly because of poorly written readers.

Understand the headers - especially if-not-modified.

Make sure the URLs follow the path of the site. DON'T include session data, drop ugly details that are to do with the system, not the user (.php, .aspx, ?, &, etc.)

URLs are prime real estate - respect them

When you chose what to build, solve a problem you have yourself so you can be sure to understand it. Passion counts. It's cheap and easy to build stuff, so other people will be building it too.

A niche product with a limited audience is still good business (with how advertising and PayPal work)

Every day that you don't have something properly out in the world (not on an invite only beta) you're losing a chance to gain users. Get it out there ASAP.

Aggregation is often a focus of attention (latest, most active, etc.)

As the population gets larger, the bias drifts; del.icio.us/popular becomes less interesting to the original community members. Work out ways to let the system fragment in to different areas of attention.

"Spam is attention theft" - that's one of the reasons del.icio.us doesn't have a top 10 links of all time - it's an attractive nuisance.

When you've figured out someone is spamming, don't let them know – let them keep posting and just silently junk their stuff.

Make users do the minimum amount of work. But make them do something.

Understand the user's motivation: "You have to understand the selfish user" – user #1 has to find the system useful or you won't get user #2. Systems that only become useful when lots of people are using them usually fail, because there's no incentive for people to contribute themselves. The real trick is to make the user base you have want to invite more people in to the system.

Measure behavior rather than claims. del.icio.us doesn't have stars because why would you bookmark something that was no good? This way people bookmark things that they really care about rather than trying to tell the system things.

User Acceptance Testing (UAT) is important. Make the system suitable for the people actually using the system. Everybody on the team should see this in action. Labs are great but expensive. If you don't have a lab do ghetto testing in Starbucks. We did one day then two days user testing in a user testing lab.

Goals skew the results. People don't read, they cram crap in to boxes. Let people wander don't give them tasks.

You have to speak the user's language. "Bookmarks" are what you call them if you use Netscape of Firefox - most users these days know the term "favourite" instead. Half of his population (? users) didn't know what a bookmark was.

Don't make users register before they can get in to your site. Maybe even give them an anonymous account to play with. A lot of users want to know what they'll get if they register - especially from fear of giving out email address, spyware etc. You can't tell them; they're not going to read it. You have to show them.

Use Verbs - doing words - to prompt actions.

If users do have to register, send them straight back to where they were when they're done. Don't dump them on the homepage.

"Design Grammar" - if you're presenting a system that's different from how other things work (del.icio.us had novel tags, save your bookmarks to the web) you should still try to reflect the design patterns of the web.

Morals: You have to develop a sense of morals when you build your system. It's the user's data; it's not yours. Make sure they can remove themselves and their account if they want to.

Infection: Understand infection vectors for promoting your system. "Enable evangelism". RSS lets you get at users who don't use your system directly. Also think about iCal, M3U - anything that a desktop app can consume over HTTP. Do an inventory to get into every desktop app. possible.

]]>The Value Of Lifecycle Emails2013-04-01T00:00:00+00:00http://ericfarkas.com/posts/the-value-of-lifecycle-emailsSince the beginning of 2013, I've focused a lot of my development efforts on so-called "growth hacking". Whatever the connotations that term has, I have found some really good ideas reading the many blog posts and post-mortems that are floating around. We've seen solid growth at TalentSoup that's been directly related to our focus on bringing our users to the "ah-ha" moment, and clearly presenting our value prop in blog posts and other marketing content.

I've started to send out post-downgrade emails a day or two after a user downgrades from our Pro Webcomp Portfolio. For now I don't use a template, and they are not sent automatically. Some users downgrade after a month or two, others have had a Pro account for a year or more. I want each email to be different depending on how long the user has been a paying customer.

The content of the emails are simple: we saw that you downgraded, we're sorry to see you go, but thanks for being a Pro member, and here's a coupon for a free month if you ever decide to re-up. The point of the email is really just to express thanks and to put some humanity behind our company. Part of the ethos we've created at TalentSoup is that we're honest people running a legitimate business where we want our users to succeed by helping them land real work, and emails like that help reinforce the perception (which is true!). In our industry that kind of validation from our users is solid gold and we want to nurture and promote it.

Payback

I've only heard back from two users since I started sending these emails out. One was from a user on our site who let me know she downgraded because she's leaving the country for two years to work in the Peace Corps. The other was from a user I sent an email to earlier this morning. The recurring billing system we use sends out dunning emails when a user's credit card has expired, and if the user hasn't updated their billing information after 3 days, they're automatically downgraded. Apparently the user didn't realize his account has been downgraded (I am still investigating how he missed 3 dunning emails) and was eager to re-upgrade his account.

If I hadn't sent out that email to him this morning, how long would it have taken for him to realize his account had been downgraded? In that time, we would have missed out on revenue from a user who wanted to be a paying customer. At $5 a month, you might not see that lost money as a big deal, but I do. Developing a mentality where every dollar counts and every customer is important is how you grow a business. If your goal is to make, say $50,000 month, you have to make $500/month first, then $1,000, then $10,000, etc. Every dollar counts.

]]>A (Short) Rant About Working Remotely2013-01-31T00:00:00+00:00http://ericfarkas.com/posts/a-short-rant-about-working-remotelyI get emails on a weekly basis from recruiters looking for developers. The first question I respond with is, "Are you open to remote workers?", to which the answer, 99% of the time, is "No".

The reasoning is inevitably something along the lines of "They're an early stage/small company, so they want to have everyone in the office", as if being a young or small start-up necessarily means that you have to have everyone together, as if there's no possible way to build a company otherwise.

I get the reasons why face time is important. This is why even companies that are advocates of remote work, like GitHub and 37signals, have company-wide meetups at least once a year. Even an arrangement where a dev can come in once a week, or when needed during crunch time for a project or a special planning meeting, seems reasonable. But I don't see a reason why, in 2013, given the tools we have, a developer has to be on-site at a desk every day, as the normal operating procedure. Think of how many times companies miss out on really good developers just because they're not open to remote workers.

I joined TalentSoup as a technical co-founder, and worked for a year and a half with my partner before we met face to face. All communication was done on the phone, through email, Basecamp, GitHub, iChat, whatever. We built (and continue to build) a profitable company, completely remotely. So I just don't get the reluctance from other companies to embrace remote workers. Are the problems you're working on that difficult, is your product that special, that everyone needs to be in the same room every working day?

I'm really disappointed at the state of remote work in the startup universe. Hopefully it will change in the coming months and years as companies realize the resources that exist outside of their small part of the world.

]]>Setting up statsd + graphite on Ubuntu 12.04 LTS2013-01-18T00:00:00+00:00http://ericfarkas.com/posts/statsd-graphite-ubuntuThere are many great tutorials about setting up statsd and graphite, specifically on Ubuntu 12.04. The best walk through I found was https://github.com/janoside/ubuntu-statsd-graphite-setup. I'd like to add some things that were left out of that tutorial that I had to figure out.

Database Creation

The above Gist leaves out the initial database creation. Be sure to thoroughly read http://graphite.wikidot.com/installation so you know at which step to create the db. I did this step after configuring Apache but before restarting the server.

WSGISocketPrefix

If you see an error message similar to the following:

(2)No such file or directory: mod_wsgi (pid=19506): Unable to connect to WSGI daemon process 'graphite' on '/etc/apache2/run/wsgi.19365.1.1.sock' after multiple attempts.

That's a clue to edit

/etc/apache2/sites-available/default

and make sure that the configuration for WSGISocketPrefix is set as follows:

See Also

]]>Learning - Interesting Array Manipulation2013-01-03T00:00:00+00:00http://ericfarkas.com/posts/learning-interesting-array-manipulationI said in the post about my 2013 learning plans that I'd blog about whatever I learn, even if it's dead simple or something I should have known already. This is my first such post.

Let's start with this array:

a=[1,3,5,7,9]#=> [1, 3, 5 , 7, 9]

We can replace two elements with one using the following notation:

#=>a = [1, 3, 5 , 7, 9]a[2,2]='foo'#=>a = [1, 3, "foo", 9]

Think of a[ 2, 2 ] = "foo" as meaning, "starting at index 2, replace 2 elements with the following value". We can modify the same notation to insert a value but not replace anything in the array:

#=>a = [1, 3, "foo", 9]a[2,0]='bar'#=>a = [1, 3, "bar", "foo", 9]

The above has the same effect as doing a.insert(2, "bar").

The range notation can also be used to replace a range of elements, like so:

Think of this as "replace elements at indexes 0 to 3 with the following". The interesting thing about both of these methods of array manipulation is that the number of new elements you're assigning doesn't have to equal the number of elements you're replacing. Using our original array, I can do the following:

That's approximately 2200 pages (Programming Ruby is 944 pages but the second half of the book is language reference which I won't be "reading"). So 2200/365 is approximately 6 pages a day, or 42 pages a week. Some of the books I am reading will cover material I am already familiar with, but I personally find it helpful to consistently review the basics.

I will post my progress here. In the past I have been embarrassed to write about the things I am learning because I feel others have said it better already, and perhaps I'm posting about things I should have known already. But that is a counterproductive mindset to have. First of all, it betrays a conceit that anyone actually reads these posts in the first place. Secondly, it keeps me from engaging in what is one of the best ways to complete the learning experience, and that is to write about it and teach others.

I'm looking forward to firming up the knowledge I already have, and getting deeper into Ruby, the language I have come to love. I'm also excited about digging into an open source project that I have used and admire, and learning from the masters.

The Dubbel

When the dubbel was meant to be "ready" (about 3-4 weeks in the bottle), I thought it was a failure. It had a soapy aftertaste, which I identified at the time as being caused by the beer being left in the fermenter too long. It was in the primary for one week, and secondary for 11 days. Eighteen total days. Not a long time by any stretch, but I was a new homebrewer, and what did I know?

The problem with screwing up a beer is that now you have 50+ bottles of homebrew that you really don't want to drink, and you don't want to let your friends drink either. So I did what any embarrassed homebrewer might do: I just let it sit in my dark, cool basement for months.

It turns out this was the best thing I could have done.

A couple of nights ago, I had a meeting to attend, and someone had to bring the beers. Weeks earlier, I had thrown a couple of bottles of the dubbel in with some other beers to make a six pack for a night out. Perhaps some of my friends who didn't have much experience with craft beer wouldn't notice the off flavor, and they might enjoy it. Turns out the beer got positive reviews from those friends. Buttressed by that feedback, I dared to bring a six pack of my homebrew to that meeting. Maybe the soapy off-taste had dissipated a bit, and I could start to unload my failed homebrew.

I cracked open the bottle, and poured it out. It wasn't as carbonated as it had been when I first tried it months ago. The head was legit, and it smalled fantastic. I let it warm up and breathe, and took my first sip. The flavor had totally changed. Gone was the soapy after-taste, and the beer actually had a bit of complexity about it that was absent originally. At 7.3% ABV it had some kick, but whereas in January the alcohol slammed you in the face, now it was more subtle, masked by the dark fruit, malty flavors of the beer.

The Saison

A similar, though less dramatic thing happened with a saison that I brewed in July. With the purchase of a new boil kettle, I was dialing my process in. Armed with what I thought I had learned from brewing the dubble, we had a nearly-flawless brew night on July 21. Four weeks later, the saison was ready to drink.

I really liked this beer initially. My only criticism at the time was that the yeast flavors were a bit overwhelming for that style. This will come off as snobbish, but the prominence of the yeast was something most folks wouldn't have noticed unless they were regular drinkers of farmhouse ales. No worries, though, because it was a good tasting beer, with no discernible off-flavors. I was proud of it but I'd probably still make a run to the beer distributor if we were low on other beers, instead of reaching out for my own homebrew.

But last night, my wife and I were watching a movie, and had a huge bowl of homemade popcorn. Naturally we had to have some beer, but we were out of everything. There were no cold dubbels in the fridge, only one saison. I hadn't tried the saison for a while, so I poured it into a glass, and the first sip made me think it was a different beer. The yeast had taken a back seat to these overwhelmingly tasty fruit flavors. The carbonation was there as well. My wife and I both remarked that this was a beer we'd go buy in a store, and choose over other craft brews. I was now in the position of having a couple of month's worth of delicious homebrew in my basement!

Lessons Learned

Experiencing my beers on those two occasions, after having brewed and then tasted them throughout the intervening months, was surreal. You're holding a drink in your hand that you quickly realize is a living thing. It's evolving. There's yeast in that bottle that's doing something. Now, every beer has a "drink-by" date, past which you no longer realize the benefits of aging. But a huge lesson for me is that I need to give my beers time to come into their own, and let nature takes it's course.

On a macro level, this is a huge lesson to learn for life in general. There are things which I have no control over, though I wish I did. "The recipe said the beer will be ready 4 weeks after bottling, and it's 4 weeks later, so this beer better be ready now!" But yeast doesn't really care what I want, or when I want it. It's going to do it's thing in it's own time. There is, to borrow an idea from Ken Myers, a "givenness" to beer making that resists attempts to impose a timeline on it. Sure you can tweak things in your process, but you're ultimately at the mercy of the yeast.

One of the reasons I got into homebrewing was that I thought it'd be good for me to have a hobby that requires patience, and that does not give immediate feedback. As a programmer, my life is all about instant feedback. I can start with an empty app, and in a few minutes, with basic models, controller actions, and tests, have a working system. It won't be perfect, but you can push this button and stuff will happen. Making beer is not like that. The brewing process takes hours, the bottling process takes time and attention to detail, and then you're waiting weeks for the beer in the bottle to be ready, and even when it's "ready" it might not be truly ready (as my experience has now shown).

There's a part of me that's afraid of the negative effects of technology on my soul. Just in the act of software development, I unconsciously create habits and expectations that spill over into other areas of my life. But unfortunately, there's not a 1:1 relationship between software development and being a good father, for example. In the former, I can sit down in front of my laptop and clear a bug list in a couple of hours, and those bugs will (hopefully) never appear again. In the latter, it might take days, months, years for my wife and I to work through issues and establish good habits with our children, or within our marriage. And even then, constant vigilance is required to fight against sinful relational tendencies, or to reinforce good habits through the discipline of repitition. Does my work in and use of technology prepare my soul for that fight? More and more I think it does not, hence my journey into homebrewing, and also a big reason why I've disciplined myself to work out strenuously on a regular basis.

These two things (homebrewing and working out) are valuable to me for the counter-balancing practices and insights they yield relative to my day-to-day experience. The Bible is always my source of ultimate truth and illumination. But I have found it helpful to force myself to do things that are not comfortable precisely because they put "flesh" on the things I believe about what constitutes human flourishing.

This lesson, about giving something time to evolve and mature on it's own terms, and providing the environment in which it can flourish while having the patience to let the process happen, is one I'm happy to have experienced.

I'm even happier that I didn't throw out those bottles of homebrew.

]]>Dynamic Images (Or A Lightweight Gravatar)2012-10-03T00:00:00+00:00http://ericfarkas.com/posts/dynamic-images-or-a-lightweight-gravatarWe recently rolled out Creative Commissary, our project management tool for image producers. It's a completely separate app from TalentSoup in every way. They do not share databases, and communicate via a JSON-based RESTful API. Clients build and manage projects in Commissary, and the talent details (name, contact info, etc.) are stored in TalentSoup.

In TalentSoup, talent have the option of selecting any of their photos as the main photo. This is the photo whose thumbnail will be shown in search results and project galleries. This main photo is the talent's first impression on the client, and therefore the talent's most important photo.

Originally, when doing a search return (Commissary sending search parameters to TalentSoup, TalentSoup returning a search result to Commissary), I was including the static URL for the main photo at the time of the search as the main_photo value. This value would be stored in Commissary and would be referenced when rendering a gallery page for the client to look at. One thing I didn't take into account, however, was that talent might change their main_photo anytime after the gallery for that particular project was built. When that happened, the image being displayed in the gallery wouldn't change, because the URL was being stored statically on the Commissary side.

This is a problem because sometimes talent change their main_photo based on what type of project they're being considered for (we let them know when they're added to a gallery, and what type of job it is). For example, right now we're managing a job for a client who is going to be photographing people running. As a result, some talent changed their main_photo to show them running or doing some sort of physical exercise. This should be reflected in the galleries, obviously!

Basically what I needed was a service like Gravatar. One URL I could pass around between TalentSoup and Commissary that would always render the given talent's main_photo. I came up with a simple solution. I am not sure if this is the best way to accomplish this, but it works. Here's a controller action that lives on the TalentSoup side:

And I'll always get the main_photo for a given talent even when they change it. We can make this more efficient by caching on the TalentSoup side, and invalidating when the talent changes their main photo.

]]>Sinatra, ActiveRecord, and MySQL2012-09-06T00:00:00+00:00http://ericfarkas.com/posts/sinatra-activerecord-and-mysqlIf you want to use ActiveRecord with Sinatra, the sinatra-activerecord gem is the way to go. The examples in their documentation are for the sqlite3 adapter. I thought it'd be helpful to show how I used this gem with MySQL instead. I created a models folder in my app root, where I store my ActiveRecord models. You can include all of them in one file (like models.rb) or give each model it's own file, and include it explicitly. We'll use the former for this example.

See Also

]]>On Child Rearing2012-09-01T00:00:00+00:00http://ericfarkas.com/posts/on-child-rearingThe following was written by my pastor, Ben Miller, as counsel to a family raising a young child. I've been given permission to reproduce the letter here. The only modifications have been to remove references to specific names and life situations.

Hi, [redacted],

I wanted to follow up on our brief conversation last night. I know the parenting issues you're sorting through are really difficult, and I'd like to offer whatever encouragement and counsel I can. I doubt I'll say anything here that you haven't already thought of, but maybe something will at least provide an additional perspective.

1. As you know, the goal in parenting is not to bring forth a product that meets the specifications in some pre-printed blueprint somewhere. There isn't a preformed set of specifications "out there" that says, "This is exactly what it will look like for your child to be Christlike." That may be obvious, but what it means in practice is that it's okay as parents to feel (pretty much every day!) a bit unsure of the best way forward. We ourselves are still discovering what the particular "product" is supposed to be, and sometimes our methods have to be retooled significantly as we move along in that discovery process. You know from scripture that your child is to be conformed to their Lord and Savior Jesus Christ by the power of the Holy Spirit, but what you don't know is what precise form that will take (which, of course, means you're still learning every day what are the best methods to guide them toward their individualized conformity to Jesus). In short, if you feel uncertain, that doesn't mean you're blowing it!

2. On a related note, your child is not a problem to be solved, but a gift to be enjoyed and a mystery to be wondered at. This doesn't take anything away from the fact that they must be trained, but there's a world of difference between (a) training a child you have come to regard (not at all maliciously, of course, but simply because you're tired, perplexed, and frustrated) as a "problem child," and (b) training a child from whom you constantly step back and say, "What a wonderfully mysterious gift God has given us here." Part of the reason you get overwhelmed in training your child is that they're beyond figuring out - and God made them that way! We need to back away as parents sometimes and simply enjoy that.

3. In light of the medical issues, remember that your child is much more than a physical body; and remember also that they're much more than a will to be subdued. At the center of their being is something the Bible calls the heart, and your ultimate goal in parenting is to win their heart to you and to their Triune God. "My son, give me your heart" (Proverbs 23:26); that's parenting in a nutshell. It can be unclear, when children are very young and don't communicate well, just how to interact with their hearts; but as they get older and begin to talk, you get significant glimpses into their hearts every day, and you will have many, many opportunities every day to reach into their hearts with the love and truth of Jesus. This doesn't always mean talking to them; it means, for example, being glad (or at least acting glad!) to see them when they get out of bed in the morning, reaching out to touch them when they come near you, smiling at them, pointing out to them the good gifts of God, speaking scripture in their hearing, being careful of frustrated tones and gestures and even "vibes," being quick to restore affection after the sharpness of discipline, speaking well of them to others, noticing the little things they do that they yearn (yea, clamor) for you to notice, etc. Children need to feel drawn in by their parents, not pushed away (overtly or covertly). Again, the goal is to establish a bond of affection heart-to-heart that will then open their ears when it's time to rebuke, chasten, and instruct.

4. Again in light of the medical issues, you will continue to learn every day how to balance meeting your child's needs (which are real) with the dark reality that they (like all of us) will use their needs to manipulate you to get what they want. One of your child's needs is to know that when they push against a clear (and reasonable) boundary you have set, it's not going to move. Nothing breeds insecurity in a child so much as not knowing who's in charge. As you build the bond of affection I mentioned above, you will find that your setting and enforcing of boundaries will not frustrate your child (though they may still resist, just to make sure you truly mean it), but will give them great comfort and reassurance.

5. One of the hardest things to learn in parenting is when to skirt a particular battle in order to win the war. There are certain things your children are doing to do every day that are going to drive you insane, and now is simply not the time to address them. There is always a need to prioritize "battles" in the long "war" to win the hearts of our children. A parent who can't wisely prioritize, and then let go of certain things for the present, is going to be a parent who eventually gets completely overwhelmed - and heaven help the kids at that point!

6. Connected with this, I would suggest that you both sit down and hammer out a set of (by this I mean two or three) simple, clear, attainable goals for your child's development (say) over the next three months (or six months), and then teach and discipline diligently, consistently, and unswervingly to those. Other stuff will have to wait. You don't build a roof at the same time you're building a foundation. For example, this summer we're working with our kids on expressing gratitude and taking jurisdiction over particular "zones" in the house.

7. On the social side of things, listen to wise counsel from others, but don't be ruled in any way by the opinions of others. You are not bringing up your child for either set of in-laws, or Trinity Church, or the medical professionals who weigh in; you're bringing them up for the Triune God - and it is you who are called to bring them up, which means you need to be comfortable making wise decisions and seeing them through, regardless of what others think. This doesn't mean you're hard-headed and don't listen (I wouldn't be writing this email if I were trying to encourage that!), but it does mean you're comfortable with the fact that the God of all grace - and He alone - is your Judge in this business of parenting. Everything else is just human opinions.

8. [The husband], this is directed especially to you: be very careful (notice the "very" in that phrase!) about too many outside commitments at this stage in your family's life. You don't have time for a lot of outside commitments; your marriage and your children are your first priority, and whatever doesn't serve those relationships, at this stage in the game, is questionable. You need to unplug from stuff and connect with your children, especially this child. Whatever it takes.

9. Don't worry, I'm almost done! On a penultimate note, don't worry too much about visible results, especially day to day. God will bless faithful obedience. Believe that. You'll see the fruit in harvest season; right now it's planting and watering time, and it often looks like the plants aren't growing. They are, because God is at work. "Be it unto you according to your faith."

10. Above all, never let a day pass without praying fervently for the work of the Holy Spirit in all of your children. "You have not because you ask not."

With deep affection in Christ,

Ben

]]>Pipe Fabrication with QuickPen 3D and CSVs2012-08-26T00:00:00+00:00http://ericfarkas.com/posts/pipe-fabrication-with-quickpen-3d-and-csvsI've been told that it's good practice to blog about code you've written, and the thought process behind it. Doing so gives people an insight into how you approach problems, which at times is more important than what exactly you wrote. This is such a post.

My full-time job is as a mechanical draftsman for an HVAC contractor. Our work is mostly in high-end residential apartment buildings and hotels in the 5 boroughs of New York City. We build steam and water-based HVAC systems (sometimes both in the same building). At work, we use QuickPen Pipe Designer 3D, on top of AutoCAD, to draw 3D models of our mechanical piping.

A PRV station

</center>

Coordination

To get pipe to the field, the draftsmen first take the contract drawings from the architect and engineer, and we draw our pipe on the floor layout. We then attend coordination meetings, where all trades (plumbers, electricians, sheetmetal, etc.) work on a set of drawings that has everyone's "stuff" on them. This lets us resolve conflicts and hits. Pipe moves around, duct gets raised or lowered, and so on. When all trades sign off on the drawing for a particular floor, the draftsmen are then free to go back to their offices, update their own shop drawings, and work on fabricating their pipe. The adoption of BIM and related software stacks promises to make/has made some of these steps unncessary, but many jobs are still coordinated like this.

Fabrication

The next goal for the draftsman is to hand the fitters in the shop what are called "fabrication sheets", or "cut sheets", that detail what needs to be fabricated, and what tag that piece should be given.

Fabrication pieces

</center>

In the above image, R-03 is the tag number given to a piece of pipe that is 1-1/2" in diameter, 9'-6-1/4" long, and has a 1-1/2"x3/4" tee on one end. We only want one of these pieces tagged R-03. A fitting on the end of a piece like this is called a "make-up fitting". Usually, threaded pipe like this only has one make-up fitting. The other end of the pipe is a threaded end, and the fitters put these pieces together to construct all the piping on a given floor. We send "shop drawings" to the field that detail how these pieces fit together:

Shop drawing with pipes tagged

</center>

QuickPen makes it (almost) easy to do all this. I draw my pipe in 3D, at real elevations. I then use QuickPen's ISO manager to create my fabrication pieces by literally clicking on a piece of pipe, and it's make-up fitting. QuickPen auto-increments the counter as I create pieces.

The Problem

While QuickPen makes it easy to tag your pipe for fabrication, and make a shop drawing with ballons for each tag, it doesn't make it THAT easy to create the cut sheets. When you ask QuickPen to export your Bill Of Materials so that you can make a spreadsheet to print out and give to the fabricators in the shop, you're given the option to export to a CSV. Here is what QuickPen gives you, truncated for our purposes:

And so on, for each piece. The CSV is always un-ordered by ISO number (tag number). So basically what you get is a listing of each individual component of a fabrication piece, and not the whole piece itself. Sometimes this is OK, because there are pieces that may have more than two components. But 95% of the time a fabrication piece is a length of pipe and a fitting (tee, elbow, valve, coupling, etc.). I have to massage this CSV so that it's useful to the shop fabricators.

For a while I did this by hand, which was tedious. I made mistakes as well, which were costly in real dollar terms. When union steamfitters call the office while they're standing on the 50th floor deck of a building, in the middle of winter, screaming that your pipe doesn't fit...well, that costs everyone money in wasted time and material. In this way, drafting is different from much of the programming I've done recently. Aside from the processing of subscriptions, bugs that occur on TalentSoup don't immediately result in lost money, but simply an annoyance. Drafting is different: a mistake could cost tens of thousands of dollars.

So after spending so much time on these CSVs, and making some bad mistakes, I decided to let the computer handle the CSVs for me. This problem was always begging to be solved by a script. The result is cut-sheets.

Walk-Through

Now that I told you more than you wanted to know about mechanical piping, I want to quickly walk though the parsing script.

First, I shamelessly steal Rails' blank? method, which is useful in this context. Then I set up some constants that map to the column indexes in the CSV. It's more readable this way. Then I read the CSV in as an array.

Sometimes, QuickPen's Bill of Materials generator brings in pieces of pipe or fittings that are not part of any fabrication piece. I remove them from my array so I can process the CSV knowing that I am only working with fabrication pieces. The motivation for want to assume this will be clear shortly.

fabrication_pieces_as_array.delete_if{|x|x[ISO_NUMBER].blank?}

Next, I change some of the descriptions of the pieces to conform to our shop standard. Also, if the current array element is a fitting (which doesn't have a length as it's not a piece of pipe), then I put the fitting size into the description. This is so when I make this element the make-up fitting of a piece of pipe, I get the fitting size in the description without any other manipulation.

Now that my fabrication_pieces_as_array object is cleaned up, I can start combining pipe pieces with their make-up fittings. First I create a hash using Ruby's awesome group_by method. What I get back is a Hash whose keys are the ISO_NUMBER, or tag number.

Now I can test to see how many pieces each tag number has. As I said before, 95% of the pieces I make will will have two components: a length of pipe and a fitting. For cases where the pieces are more complex, I handle those manually, usually by making a sketch of the piece in QuickPen. I'll make a note on the cut sheet to "See Sketch" for that pieces. Otherwise, I now go through my original array. For each element I test to see if it's ISO_NUMBER number has two components, and if the LENGTH column is not nil?, meaning this element is the pipe portion of the fabrication piece that also has one make-up fitting. I add the fitting row to the pipe row because the pipe row has the pipe LENGTH; it just "feels" more natural to do it that way.

Now that I've replaced the DESCRIPTION column of each piece of pipe with the corresponding make-up fitting, I can remove the rows of make-up fittings, which, again, don't have a LENGTH value. Then I sort the array by ISO_NUMBER. This is not necessary, as I can do this in Excel when add this information to our template, but it saves me a step.

Lastly, I generate a new CSV with all the pieces and their make-up fittings. Pieces that have more > 2 components are also listed, but they have not been "combined" together, so I'll resolve them manually. At the bottom of the CSV I also generate a bill of materials, which is a count of each fitting, so the shop knows how many of each to order from the supply house. Ruby's group_by gets all the distinct pieces into a hash, and then it's as simple as getting the size of each key.

See Also

]]>Eager Loading With Authlogic2012-08-23T00:00:00+00:00http://ericfarkas.com/posts/eager-loading-with-authlogicI've used authlogic for authentication and session management on a number of projects. For one application, I wanted to eager-load an association at the time of a successful sign-in. I thought it'd be helpful to demonstrate the code here, since it took some digging through the documentation and other examples to figure out how to accomplish this.

Basically you want to create a new session within a with_scope block, and pass a find_options hash with whatever options you need. Here's the create action in the UserSessions controller:

See Also

]]>What I Learned On The Track This Morning2012-08-03T00:00:00+00:00http://ericfarkas.com/posts/what-i-learned-on-the-track-this-morningToday's workout called for a 5000m row. I do not have access to a C2, so, after some consultation, I decided to run 3 miles instead. I was told to run it hard, and I set myself a goal of 3 miles in 21 minutes. I have never done 3 miles in that time. I have come close before, 21 minutes and change, in my running days. But that was 5 years and 20 pounds ago. I don't train that way anymore, I use the weights a lot and get my "cardio" from brutal circuits. My workouts for the last few months have featured no running whatsoever.

Immediately you see the problem. The ego suggested a goal, and I listened, and adopted that goal as my own. I had not put in the work necessary to achieve that goal, and I thought I could just show up and, with pretty much nothing in the bank, set a new personal best. The smarter thing would have been to set a more achievable pace, maybe 22:30 or 23 minutes. Those times are not fantastic but at my current fitness levels, and in the context of my larger training plan, they would have represented good work. More importantly, I could have finished the workout.

By now, you know how the story goes. I started off at about a 6:45/mile pace. Two laps in and I realized the hole I had dug for myself. Approaching the mile mark, I had "the moment". Faced with the consequences of my decisions, there were two paths: continue on and live with myself with integrity and suffer, or give up.

I chose to bail. One mile done, and I was done too.

In the initial moments after quitting, I tried to rationalize my decision. "My lungs hurt", "my legs hurt", "it's humid out", "one mile is good for not having run in a while". But the truth is, I made a choice. I chose to quit, I chose to stop putting one foot in front of the other. I did not have enough integrity to face the consequences of my actions. I lied to myself.

The walk back to the car from the track was tough. I took stock of other areas in my life where I had dug myself a hole that I cheated my way out of. It's not easy to come face to face with yourself as you really are, not as you imagine yourself to be.

It's interesting to me how I first thought that what I learned today was that I need to pace myself and fight against my ego. In fact, I learned that you cannot expect to achieve what you did not work for. And the answer is not always to work harder, to run yourself into the ground. Sometimes the answer is to just starting working, period.

Second, when have dug yourself a hole and find yourself in an uncomfortable situation that is of your own making, stand your ground and live with yourself. Sometimes it means suffering. In fact, it almost always does. But you come out on the other side with integrity.

I did not have that integrity today. I will have it on Monday, and every day after that. And not just on the track, or in the gym, but in all of life, with the help of God.

See Also

]]>Global Exception Handling With Bugsnag2012-07-09T00:00:00+00:00http://ericfarkas.com/posts/global-exception-handling-with-rails-3-and-bugsnagAt TalentSoup, we recently launched a new application privately to a number of our trusted customers. For exception handling, I decided to give bugsnag a try. In the past I've used the exception_notification gem, and have even rolled my own solution for handling exceptions, but for this new app, I thought I'd do something new. I'm a big fan of leveraging existing "solutions" for common tasks, so I can focus on the core business of the application (see Buy-vs-build for an early stage startup).

bugsnag has nice documentation to help you get started. What I wanted to do was just catch every exception that's generated by the app, regardless of specific type. As the app matures and we decide what we want to do in a particular case, we'll handle each exception type differently, but for now, a global catch-all will suffice:

So we catch every exception, and display a generic error page that lives in app/views/shared/. This wound up being trivial but it was a good excuse to dig into Rails 3 internals and learn about how exceptions are handled within the framework.

See Also

]]>Stuff DHH Says2012-07-06T00:00:00+00:00http://ericfarkas.com/posts/stuff-dhh-saysOne of the things that makes being a developer interesting (or maddening, depending on your perspective) is the ever-present need to learn new "stuff". Even if time does not allow you to play with certain technologies or frameworks, you should still be aware of their existence, and have a general idea of what they do and where you might use them.

The problem, as I see it, is that it's difficult to separate the signal from the noise. With so many frameworks, methodologies, data stores, servers, etc. one can feel overwhelmed quickly. A few prominent voices start touting this or that approach, and you're left with the question: do I jump on board? Or do I stick with what I know and what has worked, and potentially get left behind? These questions can affect careers. You have to learn to balance the desire to stay up-to-date with the temptation to drink the Kool-Aid and take your eye off the ball, which is the fact that, in the words of jwz, you're not here to write code, you're here to ship products. What approach or technology or framework will help you actually ship code?

Over time, I have found DHH to be a sane voice of reason in what can sometimes be an insane Rails community. The framework he created has basically furnished me a career and lifestyle, so I have a high degree of respect for him. Not only did he create the Rails framework, but 37signals has created some of, if not the most, successful Rails applications to date. When he talks about development, I listen.

In the last few weeks I've watched DHH's Twitter feed
with great interest, as he's been offering his thoughts on some of the current Rails development trends that are relevant to my projects. His approach resonates with me, as he seems to advocate a sane, simple, common-sense approach to Rails development. I've taken the time to aggregate some of his recent Tweets into paragraph form. This is helpful to me, and maybe it will be helpful to you.

On Testing and Testing Frameworks

Spurred by this debate on rails-core https://groups.google.com/forum/?fromgroups#!topic/rubyonrails-core/_lcjRRgyhC0, I'd like to see some more real FactoryGirl code gisted. All the tests I've seen written with FactoryGirl, or other factory approaches, have been worse than the equivalent fixture approach. I like @tenderlove's theory that people got hooked on factories before foxy fixtures with named associations and never revisited. That's really the sad part about both rspec and FactoryGirl. Newcomers are lead astray to these tar pits instantly. It's like most Rails books can't wait to pimp the framework ride. Hey yo, that chariot needs some spinning rims, yo! Ugh.

@rgreen: everone is pushing Rspec. Where do we go for better instructions?@dhh: See Agile Web Development with Rails and stick to test/unit as it comes out of the box.

@paulvolpato: if you don't mock often, do you tend to write unit tests where the object under test talks to real collaborators?@dhh: Yes. I don't believe much in the "complete isolation" idea. My unit tests are more like model tests and do hit the db.

On Software Architects and Architecture

It's easy to forget that there are still people who proudly call themselves software architects, use UML, and clamor for repeatable process! I was only reminded by reading http://www.javacodegeeks.com/2012/07/architects-need-pragmatic-software.html. Ugh. Here's a process for you: Software architects who don't implement a substantial amount of what they design will fuck shit up. Badly.

Following up on the discussion from @rubyrogues, this is a great example of SRR pattern wankery: http://www.naildrivin5.com/blog/2012/06/10/single-responsibility-principle-and-rails.html. Premature extraction! The over-architecture of injecting the mailer is particularly offensive. Reminds me of that thread where someone got canned for such code. Test is simple: Look at the original code and compare to the concoction that follows. Forget the authoritative pattern name. Is it better? This coordination work is exactly what the controller is there to perform. It's completely fine for controllers to be more than 1 line. (Just to be clear, I think moving the mailing action into the model is an abomination. Leave it in the controller. That's what it's for!) Preemptive programming is what happens when you just can't wait to apply your patterns until they're actually needed. I didn't think it was possible, but Single Responsibility Principle appears to be producing even more bullshit code than Law of Demeter. Love how these patterns are not supposed to bear critique in any of their examples. It's always about MAINTAINABILITY. You have to believe! If you can't provide a convincing before/after code for your pattern, you're selling snake oil. Fuck your faith-based programming bullshit.

Another example where SRR went hog wild: https://gist.github.com/2838490. Every line of activity becomes a class instead of just a method. Fuck me. (The roar of the "proper OO" crowd in that thread going rah-rah-rah is hilarious, btw.) I think having the mailer call inline in the controller is a better fit until you have more real problems tugging at it.

I'm a little late to the party, but unless you're actually reusing this PostComment logic in multiple places, I agree with your senior developer. Here's how I'd swing it in the regular controller:

I'm assuming that the language detection is something that needs to happen in the comment, so I would keep it in that model -- but not sure what it does. (In response to this thread: https://gist.github.com/2838490)

On Rails Application Design

@seandevineinc: Any advice on when to use AR observers instead of AR callbacks?@dhh: I basically do not use Observers any more. I find them too indirect. I use callbacks all the time, though. But a general rule would be that callbacks should only be used for model concerns, observers can trigger external services. So if saving a model should send an email, I'd use an observer if I couldn't do it in the controller. Not a callback.

@rdetert: what about observers for sending notifications?@dhh: I'm not a big fan in general. It makes the flow opaque. Just triggering from the controller is much simpler in most cases.

]]>Full-Time/Part-Time Co-Founder Dynamics2012-06-01T00:00:00+00:00http://ericfarkas.com/posts/full-time-part-time-co-founder-dynamicsI received a lot of feedback, via Hacker News, Twitter, and email, from my post titled How To Do A Startup On The Side And Not Lose Your Family. Based on that feedback, I have a lot of ideas for future posts. There are a lot of people out there trying to do the "startup on the side" thing while leading a full family life, and perhaps there hasn't been a lot written specifically for that group. I do not claim to be an expert, but my experience, limited though it may be, might be helpful for those folks. This post is about co-founder dynamics, particularly in the case of one co-founder being full-time, the other being part-time.

As with my last post, this is simply my n=1 experience. What follows is not meant to be prescriptive but rather descriptive. It might seem crazy and foolish but it works for me.

School of Hard Knocks

In 2005, 3 of my friends and I created a social networking startup. My 3 co-founders were working on the project full-time. I had just gotten married, and was one year into a great job as a Java developer at a large bank in NYC, with a baby on the way. There was no way I was leaving that situation to chase the dream full-time. So our setup was 3 full-time guys, me part-time, with the expectation that through either revenue or investment, I'd one day be able to work full-time. I wound up leaving before I had that opportunity, after about 18 months. I was terrible at balancing work/life/startup, and the strain on my young marriage caused me to neglect working on the startup, which was not fair to my co-founders. A graceful exit was the best option for all parties.

In 2009 I joined TalentSoup. My co-founder, Rad Harrell, had started the company in 2006, and brought me on board as a technical co-founder. The setup there was similar: Rad does TalentSoup full-time, it's how he feeds his family. I do my work part-time.

So that's my experience. Two startups, both done part-time while my co-founders were full-time. The first was unsustainable for me, my involvement in the second is still going strong after 2 1/2 years.

Qualities To Look For In A co-founder

Before discussing the dynamics of how co-founders work together, let's take a step back and talk about beginning that relationship in the first place. Much has been written about the qualities to look for in a co-founder, technical or otherwise. To me, the most important thing is character. Do they value what I value? Are their priorities, even if they don't have a family like me, the same as mine? Do we have common ground on which to relate to one another, and understand each other? Is this person not only trustworthy, but open and honest? These are not trivial concerns. Doing a startup is very similar to a marriage in that, in many ways, you are sharing a part of your soul with another person. Anything that you find mildly annoying or grating about the other person will certainly show up, magnified 1,000 times, in a co-founder relationship, especially one that takes place in the context of having a family and other external pressures.

Trusthworthiness, which is the part of character that's the most important to me, is a tricky thing to test for. I've lived and worked in New York my whole life, and as a result I've developed stereotypical New York cynicism. I default to "I'm not buying it". This cynicism, while sometimes harmful in other areas, is absolutely an asset for testing trustworthiness. When someone speaks to me, does my instinct incline me to believe them, or dismiss what they're saying? I think I have a good instinct for that kind of stuff, developed over time, having heard dozens of startup ideas and talked to countless people.

This came in handy when I first spoke to Rad. We had a phone conversation for an hour, and he pitched me on the project. He was open about everything: the past, the current state of the company in all areas, what his vision for the future was, and what he was willing to give to get me on board. There was a recognition that I would be the technology lead, that his expertise was limited in that area, and I'd have freedom to do what I felt needed to be done. You might think that's too much information to give in a first discussion, but his openness, as well as my gut telling me that this guy was being absolutely real with me, endeared me to him. I remember telling my wife that I liked Rad so much after that call, I felt like I wanted to do the startup just to see him succeed, never mind what would be in it for me.

This whole trust thing is the cornerstone to the whole co-founder relationship. As you'll see shortly.

The Dirty Details

So now you've found a co-founder. If both of you are going to work full-time, it's pretty easy to decide you'll split the equity somewhere around 50/50. But what if one of you works full-time while the other works part-time? How do you split equity? This is where things get tricky.

Keep this in mind: your number one goal in a startup is to ship something people want. Especially in the early stages, work has to happen at a fast and furious pace. You are in constant shipping mode. Whenever you're actually sitting down, working on your startup, a couple of hours wasted on anything other than shipping code is a disaster. Keeping this in mind will help in two ways when deciding equity splits:

Even though figuring this split out is very important, it's not the most important thing.

When you're spending energy on anything in an early startup (including equity splits), you're asking: "How will this help me ship code?"

That second point often gets lost in the mix when these discussions take place. I've seen things like this: "I'm full-time and I get X%, my part-time co-founder gets Y%, and when he goes full-time, I'll have X-10% and he'll get Y+10%". I've been the guy on the other side of that equation, and I can tell you that it doesn't motivate me to know that I get more equity if I am full-time. In fact, I think knowing that there's more % waiting for me if I can just cross the full-time chasm actually stresses me out, which affects me emotionally, which affects me mentally, which negatively impacts my ability to...wait for it...ship code. Call me weak-minded but that's how I'm wired. You might be different; n=1. Maybe the aforementioned approach works for your personality type, in which case, do it!

So whatever you are thinking the percentage splits are, might I suggest just making them that way from the start? Of course everyone should be vested, and the appropriate contractual steps should be taken to ensure everyone's backs are covered. But if, as the full-time guy, you really trust your co-founder, and really trust that he's working as hard as he can to make the company a success, then why not start with whatever your "when you're full-time" percentage is? If you can't trust your co-founder, then maybe you should find another one.

Notice I am not suggesting hard and fast percentage amounts. There are alot of considerations: which one is the technical co-founder, and therefore actually building the product? Are both? Are neither? Has either partner invested money into the company for bootstrapping? Is the business existing and profitable already? In these discussions, be open and honest with your wants.

It comes down to this: the equity split shouldn't be used a carrot on a stick, but rather as a tool to create good morale for the people involved in the startup. By all means, vest, and CYA with contracts, etc., but at the end of the day, you either trust your partner or you don't.

Actual Working

You have a co-founder, and you have all the equity stuff worked out so you'll know how many millions you'll get when Google acquires you. You want your Ferrari in red, right? With black leather? Sure, we can do that.

Now you get to work. You hustle and make the most of all the time you have, balancing as you go. You make use of things like Basecamp, Campfire, iChat, text messages, etc. to communicate asynchronously. And you don't IM your partner about a bug, you open a new issue in GitHub so he can look at it when it's convenient for him, and you both have a log to refer back to. If you're a non-technical co-founder, you learn basic HTML so you can do copy work on the site, and you learn how git works so you can be involved. Spencer Fry wrote a great post about this a while back. If you're the technical guy, you look at how you can make your co-founder's life easier through automating common admin tasks. Most of all, you...chill out. If your co-founder takes a night, or two, or three off, it's ok. Because you trust him. He's not "deceiving me by not working for his fair share", he's doing what he needs to do, and when he gets back you know he's going to kill it.

TalentSoup was an existing business making money when I joined, but it was not a freestanding entity. That's changed. We've automated many of the administrative tasks around the site, things Rad was doing manually, or tasks he wanted to do but could not. This increased efficiencies, meaning we could do more work in less time, and therefore make more money because we could handle more jobs simultanenously. We could focus on serving clients and not on the tedious stuff. I also conceived and implemented our paid subscription service, Webcomp Pro, which created a new revenue stream. In other words, I am not just building features that Rad dreamt up. I am actively involved in product development, short-term and long-term, always on the lookout to create revenue through increasing our efficiency, or introducing a new product. I am a partner in the business, with an equity state that makes me happy and frees me to think about shipping code, not chasing a carrot.

Flexibility in the when and where is also very important. Don't set a "minimum expected hours per week". If you're working with someone who has a full-time job and family, and you add the expectation of X amount of hours per week on top of that to justify an equity percentage, it's going to be more harmful than helpful. I speak from personal experience, being that family guy. Now of course, if over the long term your partner is not pulling their weight, then you say what needs to be said, or do what needs to be done. But I like the idea of judging based on results only. If I am consistently shipping code that customers are using, and we are making money, does it matter how many hours I worked last week, or that I worked those hours in my boxers in bed late at night while everyone is sleeping? No, it does not. Ship code. Everything else is details.

You also celebrate success, however small. New feature launched? Let's have some beers together over iChat. First paying customer? Alright! Our 1,000th user just signed up? Let's take the night off and take our wives out. Working asynchronously, in different locations (Rad is in beautiful Savannah, GA and I am on Long Island), means you have to be intentional about building the camraderie that being in the same room would normally bring. It's not easy, but it can be done. Sometimes I laugh at myself for the ridiculous things I celebrate, like fixing an annoying bug or changing the layout of a page, but then I remember these small celebrations are necessary because they give me an emotional boost, which helps me ship code.

Choose Your Own Adventure

I was on a job interview once, and the person interviewing me asked what I consider success to be, just generally, not necessarily with relation to work, though it could be that. Whatever came into my mind. My honest answer was that success to me meant having a strong marriage, and children who grow up to love me and love God as well. I was kind of surprised by my answer. Before any business achievement, that's how I define success. And given that, my relationship with my co-founder makes perfect sense. And he is the same way (step 1: same values). We want TalentSoup to succeed financially. I want to make a lot of money; I am not embarrassed about that. But more than that I want to have a strong family, I want to live a good life and enjoy it. So I work hard, yes, but I also remember to relax and slow down. I don't stress about what Rad is or isn't doing, because I trust him, and he trusts me. If something needs to be said, either of us would say it. And if things completely broke down, there are legal structures in place to protect both of us. But I don't operate out of that. I operate on the assumption that we're both trying to build something beautiful together, in good faith, and if over a short period of time life gets in the way, that's ok.

If you're doing a startup on the side while you have a family, you're already choosing a difficult path. Don't make it worse by partnering up with someone you can't trust.

]]>How To Do A Startup On The Side And Not Lose Your Family2012-05-30T00:00:00+00:00http://ericfarkas.com/posts/how-to-do-a-startup-on-the-side-and-not-lose-your-familyIn October 2009, I joined TalentSoup, as the technical co-founder and lead developer. There's a really crazy story about how I wound up finding Rad Harrell and TalentSoup, but in short, I answered a call for help in this tweet and the rest is my history. Oh, and the first thing I did when I joined TalentSoup was ditch Drupal for Rails.

My So-Called Life

I was at the time, and still am, gainfully employed as a mechanical draftsman for a large and well respected HVAC contractor whose work is mainly in the 5 boroughs of NYC. The story of how a guy who has been programming since the age of 12, has a BS in Comp Sci and spent the early part of his career as a developer in the financial industry ended up doing mechanical drafting is also a long story, but one for another day.

As of this writing, I am 29 years old. I am the married father of three great kids. I have a mortgage. In addition to all of that, and my full-time job as a draftsman, and TalentSoup on nights and weekends, I have the following obligations and interests:

Not to mention generally hanging out and enjoying "the good life". I also have very strong convictions about not doing or thinking about work on Sundays. So if a day is 24 hours, and I need to sleep at least 6-8 of them, and I only really have 6 days of the week in which to do all of the aforementioned "stuff", how do I fulfill all my obligations?

What follows is my own n=1 experience. Every person, family, and life situation is different. Here's what's worked for me and helped me bootstrap a debt free, profitable company while having a day job, a family, and a life outside of programming.

Buy-In

By far the biggest win in my situation is the support of my wife. She not only tolerates my involvement in a startup, she actively supports me and roots for me. She wants to see us succeed. She knows and loves my co-founder and his family. She asks about the business, unprompted. All of these things together make the situation workable. Without her support, there's no way I could do a startup and have a healthy marriage and family life.

Priorities: How Do They Work?

Spousal/SO support is the first step. The second step is just as important, and closely related: establishing priorities. Every post I've ever read about doing startups with a family talks about establishing priorities, but the actual process of doing so is taken for granted. I don't think it should be. Again, this is n=1 for me, but I've learned to go about making priorities by thinking about my life in this following manner:

Inner Life

The book of Proverbs says "Keep your heart with all vigilance, for from it flow the springs of life" (4:23). Everything I do in life is affected by the state of my heart. Am I depressed? Happy? Anxious? Angry? All of these heart conditions affect the way I interface with my wife, kids, friends, co-workers; they affect the way I do my work and my outlook on life in general. It's a virtuous/vicious cycle: the happier (or more depressed) I am, the better (or worse) I work and live, which makes me happier (or more depressed). Therefore my first priority is to "keep my heart". I do this through prayer, meditation, and Scripture reading, and by regularly being part of worship.

Relationships

In reality, those categories mentioned above are not water-tight. They spill over into each other, going up and down the chain. My inner life affects everything that comes after it, but that doesn't mean my work doesn't affect my inner life. With that said, I next consider relationships, the most important being with my wife, and after that with my children. Even with my wife's support, there are times when she needs personal time with me. A common text message I send to my business partner is "Nikki needs a night, I'll see you tomorrow". We'll get some good Belgian ale, make popcorn, and watch a movie. A simple night, but we reconnect, and that's important. There has to be a give and take.

Time with my kids, especially at their young ages, is important as well. I have a lot of room to improve in this area, but the best advice I can give when it comes to time with your kids is "be present". It's so easy to be with my kids physically, but mentally be thinking about a bug that needs fixing, or a feature I'm in the middle of working on. It takes intentional effort to be mentally present. One thing that's helped is taking notes throughout the day, either with Field Notes or in Basecamp. Being diligent in this regard means I'm less stressed about losing an idea or thought while I'm away from my computer. When the kids are asleep, I can just check on the notes I've left myself throughout the day.

Provision & Employment

These two are so closely related, they warrant being discussed together. As a man, with a family depending on me, I have to be sure I am providing for them, materially. This means food on the table, clothes on their backs, heat in the winter, etc. The primary means of doing this is via a regular job, which I have. Being that my day job provides most of the money my family depends on, I need to make sure my startup pursuits do not affect my day job. When I am in the office, I am working hard. That means not working on startup work on my boss' dime. It also means being mentally present at work as well.

Obligations

Responsibilities that I have that fall outside of the employment/provision spectrum would be something like be an elder at Trinity. Right now, being an elder is the only thing I do that falls in this category, and most of my elder work (besides a meeting once a month) can take place at home through email or on the phone. But this work is something my family and I highly value, and are committed to.

Startup

Turns out that the thing which occupies my mind (and my dreams) most of the time is, in reality, further down on the priority chain than you'd have thought. Not much really to say here. If you've read this far, you know what doing a startup is like.

Enjoyment

This is a catch-all for any activity I enjoy that, while personally fulfilling, is spent apart from my family and/or does not contribute to the provision need mentioned earlier. Working out, reading, etc. Again, enjoyments are one way to improve my inner life, so even though this is last on the list, it's also important, but not as important.

Tying It Together

So now I have my priorities, listed in my order of importance. Realizing that they are all related, I nevertheless run every opportunity through the priority framework, and ask the question: where does it fit? Given what's been going on in my life in the last couple of days/weeks/months, can I pursue this opportunity without harming something higher up the priority chain? For example, I enjoy playing soccer. My brother and his buddies regularly play on Saturday mornings at a high school not far from my house. Most weeks, given how busy things normally are, I would not be able to justify spending a Saturday morning away from my kids doing something like that. It doesn't contribute to anything above "enjoyment" in the priority chain, and whatever small "inner life" benefit I'd get by playing soccer would be negated by the harm it'd do to my relationship with my wife and children, knowing that dad had a free Saturday morning but spent it kicking a ball around instead of taking us out to breakfast.

There are times, however, when for some reason I've been able to spend a good amount of time with my kids during the week, and taking a few hours to play soccer on a Saturday isn't a big deal. It's a play-it-by-ear situation. But most of the time, if I have free time, I try and spend it with my family instead of for myself.

I also have to turn down some legitimate provision opportunities as well because of the harm they'd do to my relationships. A full-time job and part-time startup take up a lot of energy, and adding something like a short-term consulting project to the mix, even though it may pay well, is something I can't do. In the last year I've turned down 3 such opportunities.

Likewise, there are some jobs I wouldn't take because of the impact it'd have on my family life. Things like consistently long hours (in a day job) are a deal breaker for me. That might disqualify me for a job at many web startups, and that's OK with me. Marco Arment recently had a great post titled Old Farts Know How To Code that sums up my feelings on the matter.

Practical Tips

Get your spouse or SO's buy-in. Until that happens, I'd suggest not going forward.

Take time to focus on your inner life, in whatever way makes sense to you.

When you're with your family or friends, "be there" mentally. Chances are, that bug or feature can wait.

Beg, borrow, and steal...time. I've started bringing my laptop to my day job, so I can work on TalentSoup during lunch. That's 5 extra hours a week. Sometimes I wake up early and work before my day job. Many nights I stay up late so I can work when everyone's asleep, without taking time away from my family.

Something has to give, and it's usually your hobbies. I've made a rule that if I do not workout in the morning before my day job, then I can't work out for the rest of the day. This forces me to pursue my "hobby" on my time, so I don't take time away from my family or startup.

On a regular basis, leave the laptop on your desk and take your kids out for ice cream, or go for a walk around the neighborhood. Life is short, and you don't get these years back. Be flexible.

Turn off the iPhone. Easier said than done, and I guarantee I am a worse offender than you. But it needs to be done.

I certainly do not keep these guidelines as well as I should. But I am learning, and I'm a lot better at balancing my time now than I have been in the past.