Adarsh PanditPersonal Bloghttp://adarsh.io/2016-10-11T20:00:00-04:00Blog AuthorUse an Underscore When Memoizing in Rubyhttp://adarsh.io/use-an-underscore-when-memoizing-in-ruby2016-10-11T20:00:00-04:002016-10-20T19:15:12-04:00Adarsh Pandit<h2>TLDR;</h2>
<p>Do this:</p>
<pre class="highlight ruby"><code><span class="k">def</span> <span class="nf">expensive_method</span>
<span class="vi">@_expensive_method</span> <span class="o">||=</span> <span class="c1">#something</span>
<span class="k">end</span>
</code></pre>
<p>Not this:</p>
<pre class="highlight ruby"><code><span class="k">def</span> <span class="nf">expensive_method</span>
<span class="vi">@expensive_method</span> <span class="o">||=</span> <span class="c1">#something</span>
<span class="k">end</span>
</code></pre>
<p><img src="/images/memo_pad-9e03d548.png" alt="Memo_pad" width="800" height="600" /></p>
<h2>Memoization Basics</h2>
<p>The act of “memoizing” a method means to
locally cache the result of an expensive operation
on the first method invocation
and reusing it thereafter.</p>
<p>It is functionally equivalent to:</p>
<pre class="highlight ruby"><code><span class="k">def</span> <span class="nf">expensive_method</span>
<span class="vi">@expensive_method</span> <span class="o">=</span> <span class="vi">@expensive_method</span> <span class="o">||</span> <span class="n">this_expensive_operation</span>
<span class="k">end</span>
</code></pre>
<h2>Naming</h2>
<p>By convention,
you typically see developers name the instance variable after the method.
Likely, this is because manual instance variable accessors
used to look like this:</p>
<pre class="highlight ruby"><code><span class="k">def</span> <span class="nf">expensive_method</span>
<span class="vi">@expensive_method</span>
<span class="k">end</span>
</code></pre>
<p>Nowadays, we usually write <code>attr_reader :expensive_method</code>.</p>
<h2>Unused Variables</h2>
<p>Keen readers will note
we are actually instantiating an instance variable here.
That means we can access it from other instance methods.
Not a huge deal, but it’s intended for internal use when memoizing.</p>
<p>Enter the underscore.</p>
<p>It is convention <a href="http://lua-users.org/wiki/LuaStyleGuide">in</a> <a href="https://stackoverflow.com/questions/5893163/what-is-the-purpose-of-the-single-underscore-variable-in-python">many</a> <a href="https://prime.haskell.org/wiki/Underscore">languages</a> <a href="https://github.com/bbatsov/ruby-style-guide/#syntax">including Ruby</a>
to prepend an unused variable name
with an underscore.</p>
<p>The underscore serves as a signal to other developers
saying “Hey! Don’t use this!”.</p>
<p>We should do the same when memoizing:</p>
<pre class="highlight ruby"><code><span class="k">def</span> <span class="nf">expensive_method</span>
<span class="vi">@_expensive_method</span> <span class="o">||=</span> <span class="c1">#something</span>
<span class="k">end</span>
</code></pre>
<p>This is, of course, a style preference with no functional impact.
It’s also <a href="http://i.giphy.com/F3G8ymQkOkbII.gif">just my opinion, man</a>.</p>
<h2>Instance Variables in Controllers</h2>
<p>Also, as my friend <a href="https://twitter.com/gabebw">Gabe</a> <a href="https://github.com/adarsh/blog/pull/61#issuecomment-253646457">pointed out to me</a>,
it’s even more important to use an underscore
when memoizing in Rails controllers:</p>
<blockquote>
<p>“Since all controller ivars are available in the view,
it’s often helpful to mark ivars that should only be used
in the controller with a leading underscore.
That also allows things like this,
where <code>@users</code> is exposed to the view and <code>@_users</code> is just used for
memoization:”</p>
<pre class="highlight ruby"><code><span class="k">def</span> <span class="nf">index</span>
<span class="vi">@posts</span> <span class="o">=</span> <span class="n">posts</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="ss">user: </span><span class="n">users</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="ss">has_post: </span><span class="kp">true</span><span class="p">))</span>
<span class="vi">@users</span> <span class="o">=</span> <span class="n">users</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="ss">confirmed: </span><span class="kp">true</span><span class="p">)</span>
<span class="k">end</span>
<span class="kp">private</span>
<span class="k">def</span> <span class="nf">users</span>
<span class="vi">@_users</span> <span class="o">||=</span> <span class="no">User</span><span class="p">.</span><span class="nf">all</span>
<span class="k">end</span>
</code></pre></blockquote>
<p>It’s good to have smart friends.</p>
<h2>Further Reading</h2>
<ul>
<li>Justin Weiss has <a href="http://www.justinweiss.com/articles/4-simple-memoization-patterns-in-ruby-and-one-gem?utm_source=adarsh.io&utm_medium=blog">a nice article on Memoization</a>
including links to the history in Rails, handling nil results, and more.</li>
<li>Vaidehi Joshi <a href="https://vaidehijoshi.github.io/blog/2015/11/10/methods-to-remember-things-by-ruby-memoization?utm_source=adarsh.io&utm_medium=blog">has a nice bit on the history of memoization itself</a>.
She writes about how it dates back to 1968. (!)</li>
<li>Gavin Miller wrote <a href="http://gavinmiller.io/2013/basics-of-ruby-memoization?utm_source=adarsh.io&utm_medium=blog">a great article</a> covering when to memoize and when not
to.</li>
<li>Some gems which make this easier: <a href="https://github.com/matthewrudy/memoist">memoist</a>, <a href="https://github.com/adamcooke/memist">memist</a></li>
</ul>
On Growing Great Developershttp://adarsh.io/on-growing-great-developers2016-09-29T20:00:00-04:002016-09-30T23:10:14-04:00Adarsh Pandit<h2>You Can Either Steal Great Developers or Farm Them</h2>
<p><em>To grow software development teams, you can either steal excellent developers or you can develop them internally.</em></p>
<p><em>Everyone tries to steal but few invest in farming new developers. Those who do have lower salary and recruiting costs, better learning cultures, and improved diversity.</em></p>
<p>Here’s why you would set up an Apprenticeship program and how to do so.</p>
<p>If you want help setting up a program like this, <a href="mailto:hi@cylinder.work?subject=Saw%20Your%20Blog%20Post!%20Can%20you%20Help%20Us%20With%20Our%20Apprenticeship%20Program?">email me</a>!</p>
<p><img src="/images/apprenticeship-c2aed100.png" alt="Apprenticeship" width="640" height="428" />
<em>photo courtesy of WOCinTech (<a href="http://www.wocintechchat.com?utm_source=adarsh.io&utm_medium=blog">wocintechchat.com</a>)</em></p>
<h3>Why Steal</h3>
<ul>
<li>It’s straightforward. You have a need for help, they have skills you probably need.</li>
<li>You can buy your way out of the problem.</li>
<li>It is how everyone has hired for as long as anyone can remember.</li>
<li>Short-term impact. Expert developers can get ramped up quickly and help you ship much faster.</li>
</ul>
<h3>Why Farm</h3>
<ul>
<li>Cost - Creating a developer growth pipeline is much cheaper in the long-term. Apprentices are cheaper than experienced developers and will take a salary hit for the learning opportunity.</li>
<li>Loyalty - Apprentices are extremely loyal and less likely to turn over. You
took a chance on them and they will always remember.</li>
<li>Diversity - The experienced developer pool is very homogeneous. The junior pool
is not. If you can turn juniors into seniors, diversity will improve.</li>
<li>Vibe - Apprentices add a lot to company culture. Senior devs love to teach and
coach, so give them a chance to do so. Also, Apprentices have an energy and
optimism the old folks may have lost over the years.</li>
</ul>
<h2>Personal Backstory</h2>
<p>Back in 2012, as I tried to break into the software industry as a developer,
I got a break.
That break was <a href="http://www.apprentice.io?utm_source=adarsh.io&utm_medium=blog">an apprenticeship at a local development consulting firm</a>.
I’m still not clear how I got it, but it was amazing.</p>
<p>I made $100/day and worked 8 hours shadowing a developer consultant at a client.
In the evenings, I would stay up late Googling terms
I didn’t understand during the day and practicing new techniques on toy apps.
It’s made all the difference to my career and I’m thankful every day for the
shot.</p>
<p>After getting hired as a full-timer (and later, serving as manager),
I had a chance to interview candidates and see which ones succeeded.</p>
<p>This is what I’ve learned about how to successfully run an apprenticeship program.</p>
<h2>What is a Apprentice?</h2>
<ul>
<li>A junior developer with <em>some</em> experience. You will pay this person and train
them for a few months with the goal of hiring them as full-time employees.</li>
<li>They should be able to write and deploy working software, however simple the
app is or rough the code is.</li>
<li>Boot camp grads are usually a good fit. As of this writing, I recommend
<a href="https://www.turing.io?utm_source=adarsh.io&utm_medium=blog">Turing School</a> or <a href="https://devbootcamp.com?utm_source=adarsh.io&utm_medium=blog">DevBootCamp</a>.</li>
<li>Everyone from fresh college grads to mid-career switchers are great
candidates.</li>
</ul>
<h2>How do I Interview Them?</h2>
<h3>Use the same interview process as your full-timers</h3>
<p>Give them the same questions/challenges as your full-timers
but evaluate their responses with this lens:</p>
<p>“If I coach this person for 3 months,
would their answer meet our expectations for a full-time junior developer?”</p>
<p>This involves a bit of imagination of what someone’s learning vs. time slope
is before you get to work with them.</p>
<h3>What the Heck is a Learning vs. Time Slope?</h3>
<p>Through experience, I have discovered that each person has an internal rate of
learning.
That is, people can accumulate and apply new concepts at a consistent rate.
Imagine it looks like this:</p>
<p><img src="/images/skill_vs_time-1cac86c0.png" alt="Skill_vs_time" width="658" height="403" /></p>
<blockquote>
<p><em>For any given candidate their slope will remain constant over time,
given ongoing support. (AKA “Pandit’s Postulate”)</em></p>
</blockquote>
<p>You can use this imaginary non-quantifiable slope to both judge if they are good
apprenticeship candidates, and later, if they would be good full-time hires.</p>
<p>The trick here is to use an interview to figure out what the candidate’s slope
is. Good ol’ <code>y = mx + b</code>.</p>
<p>How do you do that? Well, you get two data points, somehow, and solve for <code>m</code>.</p>
<p>You can look at their public code samples noting the dates, and watch
progression. You can also see if their toy applications increase in complexity
over time.</p>
<p>But these are guesses. You can also run an experiment to get the data.</p>
<h3>A Hiring Case Study</h3>
<p>Once upon a time, a designer applied to work with our team.
She was very skilled as a visual designer, working mostly in print/media
at ad agencies.
She was also professional, proactive, and the team really liked her.</p>
<p>The role I was hiring for required front-end skills, which she did not have.
I gave her some homework saying something like
“See if you can rebuild your portfolio site using these tools and deploy to
GitHub Pages or Heroku.” I gave this homework to lots of non-coding applicants.</p>
<p>She was the only one to ever respond, and just four weeks later.
Now I had two data points: <code>(0,0)</code> and
<code>(4 weeks, learn enough front-end to make a portfolio site)</code>.</p>
<p>Solving for a non-numerical <code>m</code> value,
I guessed she would be ready for full-time work in 3 months.
Turns out, it was 4 months, but her slope kept constant (or improved!). So as a
result, I got a top-notch teammate and culture for a pretty small investment.</p>
<h2>Tactics for Starting Your Apprenticeship Program</h2>
<ul>
<li>Put up a separate landing page which feeds into your full-time hiring
pipeline. Run ads against it or blog/tweet about it.</li>
<li>Select for humility <em>and</em> confidence. You want candidates are willing to take a
step back to learn, regardless of their past work history or accomplishments.</li>
<li>Only take candidates excited about the apprenticeship opportunity. Focus on
people who want to learn/grow. Otherwise you’re selling something to a
reluctant buyer.</li>
<li>Respond quickly to applicants! You should do this for other candidates also.
Just sayin’.</li>
<li>Develop and document how to screen and mentor apprentices.</li>
<li>Turn down almost all of your candidates at first, to get a feel for who is out there.</li>
<li>Be very clear about it being an apprenticeship. Apprentices may not get a job
at the end, and they’ll have to work for it. Be clear about that.</li>
<li>Set a decision point at the end of two months when you make full-time offers.
This gives the candidate time to look for another job.</li>
<li>Don’t have too many apprentices at once. Maybe a ratio of 1:10 or 1:20.</li>
<li>Also, before you even start the program, you should have a few mentors who are
very excited about the program, otherwise you’re forcing something on the team
which they may resent.</li>
</ul>
<h2>Other Notes</h2>
<ul>
<li>Have retrospectives with everyone (Candidates, Apprentices, Mentors, Everyone
Else) as you go.</li>
<li>Frequently iterate based on the feedback.
Your success metric should be “number of great full-time hires made out of the
program.”</li>
<li>Make sure candidates get the same experience they’d get on the job.
This helps you evaluate the candidate and helps them evaluate you as an
employer.</li>
<li>Try to have more than one participant at a time.
This camraderie is helpful support for a pretty stressful job experience.</li>
<li>Allow candidate to set up their own success criteria
and use it to keep them accountable and measure how they’re doing.</li>
<li>Any learning the candidate does should be shared back with the mentor, maybe
in a weekly check-in.</li>
<li>Encourage candidates to network, go to meet ups, etc. Community is part of the job.</li>
</ul>
<h2>Shameless Plug</h2>
<p>Do you want help setting up a program like this?
<a href="mailto:hi@cylinder.work?subject=Saw%20Your%20Blog%20Post!%20Can%20you%20Help%20Us%20With%20Our%20Apprenticeship%20Program?">Email me</a>!</p>
<h2>Acknowledgements and Further Resources</h2>
<ul>
<li>Thanks to <a href="https://twitter.com/phonepoem">Jeremy Morony</a>, who shared his notes with me after we discussed
<a href="http://www.carbonfive.com/careers/developer-apprentice?utm_source=adarsh.io&utm_medium=blog">Carbon Five’s Apprenticeship Program</a>.</li>
<li>Lillie Chilen’s <a href="https://www.youtube.com/watch?v=75LK0MOvyjQ">great talk from RailsConf</a> on
how to run an apprenticeship program.</li>
<li>Thanks to <a href="https://twitter.com/captbaritone">Jordan Eldridge</a> and <a href="https://twitter.com/gabebw">Gabe Berke-Williams</a> for helpful
feedback and questions.</li>
</ul>
Save Money and Be Happier by Updating Your Gems Every Monday Morninghttp://adarsh.io/save-money-and-be-happier-by-updating-your-gems-every-monday-morning2015-11-15T19:00:00-05:002016-09-30T23:10:14-04:00Adarsh Pandit<p>As a newcomer to Rails,
understanding Gems and the Gemfile
is fairly straightforward:
You include a gem that you need
and you get it included everywhere.</p>
<p>We don’t often think about it,
but that last bit is important:
we are literally <code>include</code>ing
all of the code from each gem
into our application, all the time.</p>
<p>There are other implications of
this <code>include</code> behavior which should be considered,
like speed
but here I’m going to address one:
Gem Drift and the associated cost.</p>
<h2>An Example</h2>
<p>Let’s say I include an auth gem called <code>huge_bouncer</code>
in my app to do authentication and authorization.
(Note: this is not a real gem, but a name I love.
Feel free to use it but please attribute here
so I can feel good about my gem-naming skills.)</p>
<p>Over time, the nice person who wrote <code>huge_bouncer</code>
reviews issues and PRs at night and on weekends
and keeps development moving at a good pace.
She is a saint and deserves an award
or at least you should buy her a beer
if you run into her at conference.</p>
<p>Newly released gem versions are, for the most part,
new features and security patches
(particularly in auth libraries).
Not keeping up-to-date with new features
is no big deal in the short term, really.
I mean, yes, they built a nice OAuth DSL
but we don’t use that in our app, so who cares.</p>
<p>Not keeping up to date with security patches is a bigger issue.
You know who keeps up with those updates?
<a href="http://www.phrack.org/papers/attacking_ruby_on_rails.html">Bad people who want to target your innocent webapp.</a></p>
<p>You need to keep your app up to date,
so how do you do it?</p>
<h2>Enter Robots</h2>
<p>Anything you need to do routinely
should be automated, right?
You can use <a href="https://github.com/rubysec/bundler-audit">bundler-audit</a>
to regularly check for <em>reported</em> security fixes.</p>
<p>It works like this:</p>
<p>Add the gem:</p>
<pre class="highlight ruby"><code><span class="c1"># Gemfile</span>
<span class="c1"># ...</span>
<span class="n">group</span> <span class="ss">:development</span><span class="p">,</span> <span class="ss">:test</span> <span class="k">do</span>
<span class="n">gem</span> <span class="s1">'bundler-audit'</span><span class="p">,</span> <span class="ss">require: </span><span class="kp">false</span>
<span class="k">end</span>
</code></pre>
<p>Then set it up to check for vulnerabilities
when you run the test suite:</p>
<pre class="highlight ruby"><code><span class="c1"># Rakefile</span>
<span class="c1"># ...</span>
<span class="n">task</span> <span class="ss">default: </span><span class="p">[</span><span class="ss">:spec</span><span class="p">]</span>
<span class="n">task</span> <span class="ss">default: </span><span class="p">[</span><span class="s1">'bundler:audit'</span><span class="p">]</span>
</code></pre><pre class="highlight ruby"><code><span class="c1"># lib/tasks/bundler_audit.rake</span>
<span class="k">if</span> <span class="no">Rails</span><span class="p">.</span><span class="nf">env</span><span class="p">.</span><span class="nf">development?</span> <span class="o">||</span> <span class="no">Rails</span><span class="p">.</span><span class="nf">env</span><span class="p">.</span><span class="nf">test?</span>
<span class="nb">require</span> <span class="s1">'bundler/audit/cli'</span>
<span class="n">namespace</span> <span class="ss">:bundler</span> <span class="k">do</span>
<span class="n">desc</span> <span class="s1">'Updates the ruby-advisory-db and runs audit'</span>
<span class="n">task</span> <span class="ss">:audit</span> <span class="k">do</span>
<span class="sx">%w(update check)</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">command</span><span class="o">|</span>
<span class="no">Bundler</span><span class="o">::</span><span class="no">Audit</span><span class="o">::</span><span class="no">CLI</span><span class="p">.</span><span class="nf">start</span> <span class="p">[</span><span class="n">command</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Be sure to <a href="/automatically-check-gem-vulnerabilities-in-circle-ci">add it to your CI as well</a>.</p>
<p>Note there are <a href="https://appcanary.com/">all sorts</a> of nice
<a href="https://www.datadoghq.com/lpg/">paid services</a> which also do
this kind of thing.</p>
<p>Great! We’re covered, right?</p>
<p>Sorta. This will check the database
of <em>reported</em> security issues
which is some subset of released security patches.
I don’t blame gem maintainers for this:
again, they’re working in their spare time
for the greater good.
Expecting them to keep up to date
with more admin activities
isn’t really fair.</p>
<p>So what can we do?</p>
<h2>A Path Forward</h2>
<p>I started doing something on projects recently
which colleagues either don’t care about
or appreciate me doing:</p>
<p>Monday morning,
I take 15 minutes
and run <code>bundle update</code>.</p>
<p>Then I open a PR with the changes,
and hopefully deploy within the hour
once I get code review.</p>
<p>That’s it.</p>
<p>The changes are very often quite minor
and when they’re not,
I look at the gem’s release notes
and figure out what the changes are.
If it’s a big change,
say new deprecations or
breaking changes,
I fix them in about 30 minutes.
People are pretty good about <a href="http://semver.org/">SemVer</a>.</p>
<p>Remember software is best changed
in small iterations,
and updating gems
is still shipping software changes.</p>
<blockquote>
<p>“HAHA, oh great plan but we are <em>way</em> out of date already and can’t just jump right up to current.”</p>
</blockquote>
<p>Of course. So here’s what you do:
Go into the lockfile (<code>Gemfile.lock</code>)
and figure out what the specific versions
are of things which are really far out of date.
For example, let’s say <code>huge_bouncer</code>
is now at version 2.0.7,
but we don’t know what we are locked at:</p>
<pre class="highlight ruby"><code><span class="c1"># Gemfile.lock</span>
<span class="c1"># ...</span>
<span class="n">huge_bouncer</span> <span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="mi">2</span><span class="o">.</span><span class="mi">4</span><span class="p">)</span>
<span class="n">bcrypt</span>
<span class="n">email_validator</span> <span class="p">(</span><span class="o">~></span> <span class="mi">1</span><span class="o">.</span><span class="mi">4</span><span class="p">)</span>
<span class="n">rails</span> <span class="p">(</span><span class="o">>=</span> <span class="mi">3</span><span class="o">.</span><span class="mi">1</span><span class="p">)</span>
</code></pre>
<p>We can use the <a href="https://robots.thoughtbot.com/rubys-pessimistic-operator">twiddle-waka</a> operator to say
“when updating this gem,
only do so to the next major version,”
like so:</p>
<pre class="highlight ruby"><code><span class="c1"># Gemfile</span>
<span class="n">gem</span> <span class="s1">'huge_bouncer'</span><span class="p">,</span> <span class="s1">'~> 1.2.4'</span>
</code></pre>
<p>Okay so now we are not moving that much,
and can do a safe <code>bundle_update</code>
without moving the versions too much.
In this case, let’s say we get up to 1.2.8.
This is an improvement!</p>
<p>Then, when we next have time,
we can loosen the restrictions a bit,
<code>bundle update</code> again,
and see if all is okay.</p>
<p>Remember, we want to make and deploy
small changes, so don’t get all crazy.</p>
<h2>Wait, What About Robots Again?</h2>
<p>Shouldn’t you build or pay for some service
which does this for you?</p>
<p><em>NO</em>.</p>
<p>You are including a heck-ton of other code
and you should be aware of
how it is changing.
Maybe not in minute detail,
but it’s a lot of code
which you are shipping,
so you should read the label.</p>
<h2>The Money Saved</h2>
<p>No one will care if you update gems
every Monday morning
but you are saving your company
lots of money.</p>
<p>I asked some friends
to estimate the cost of
getting totally current with their gems
at their company or clients
and here’s what they said:</p>
<ul>
<li>Upgrading Rails 2 to 3 is about 16+
developer-weeks, so about a $100-200k problem</li>
<li>Upgrading Rails 3 to 4 is about half of that.</li>
</ul>
<p>Assume the bigger the codebase,
or the older it is,
the higher the cost.</p>
<p>So no, it’s not glamorous work
but someone should thank you for doing it.</p>
<p>Also, if you are up to date,
others will pick up the slack for you
<em>because you’ve made it so easy</em>.
Good job! You are a minor hero!</p>
<h2>Acknowledgements</h2>
<p>Big thanks to <a href="https://twitter.com/drapergeek">Jason Draper</a>
for helpful edits
and promising to argue with me about this
in public.</p>
<p>Also, thanks to the people who
shared estimates or anecdotes
of what it costs to upgrade
Gem suites.</p>
Bundler Failing on El Capitanhttp://adarsh.io/bundler-failing-on-el-capitan2015-11-08T19:00:00-05:002016-09-30T23:10:14-04:00Adarsh Pandit<p>After updating to El Capitan,
installing new gems
started to fail.
It looked something like this:</p>
<pre class="highlight plaintext"><code>Building native extensions. This could take a while...
ERROR: Error installing awesome_gem_name:
ERROR: Failed to build gem native extension.
checking for rb_trap_immediate in ruby.h,rubysig.h... no
checking for rb_thread_blocking_region()... no
...
CFLAGS=-O3 -I/Users/haven/.sm/pkg/active/include -fPIC -mmacosx-version-min=10.7 -pipe -Wall -Wextra -Wno-deprecated-declarations -Wno-ignored-qualifiers -Wno-unused-result
CPPFLAGS=-D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags) -Wall -Wextra -Wno-deprecated-declarations -Wno-ignored-qualifiers -Wno-unused-result
checking for clock_gettime()... no
checking for gethrtime()... no
creating Makefile
make "DESTDIR=" clean
make "DESTDIR="
compiling binder.cpp
</code></pre>
<p>But here’s the important part:</p>
<pre class="highlight plaintext"><code>In file included from binder.cpp:20:
./project.h:116:10: fatal error: 'openssl/ssl.h' file not found
</code></pre>
<h2><a href="https://www.youtube.com/watch?v=k5Cfhooa1bI">Wha happened?</a></h2>
<p>As of OS X El Capitan,
Apple no longer provides OpenSSL headers.</p>
<p>“But wait, I have OpenSSL!,” you cry.</p>
<pre class="highlight plaintext"><code>$ which openssl
/usr/bin/openssl
</code></pre>
<p>Yes you do, but you lack the <a href="http://www.tutorialspoint.com/cprogramming/c_header_files.htm">C <em>headers</em></a>
which some gems use to build
native extensions.</p>
<p>Think of the headers as the source code
and <code>/usr/bin/openssl</code> as the compiled binary.</p>
<p>Apple no longer ships the headers
on which many gems with native C extensions depend.
For more on why, <a href="https://lists.apple.com/archives/macnetworkprog/2015/Jun/msg00025.html">read this post</a></p>
<pre class="highlight shell"><code><span class="c"># On earlier OS X:</span>
<span class="gp">$ </span>ls /usr/include/openssl/ssl.h
/usr/include/openssl/ssl.h
<span class="c"># On El Capitan:</span>
<span class="gp">$ </span>ls /usr/include/openssl/ssl.h
ls: /usr/include/ssl.h: No such file or directory
</code></pre>
<h2><a href="https://www.youtube.com/watch?v=yo3uxqwTxk0">Fix It!</a></h2>
<p>You can install your own OpenSSL headers
using either Homebrew or MacPorts.
I’m a Homebrew guy so let’s go that route.</p>
<p>First let’s uninstall whatever you have,
if anything:</p>
<pre class="highlight plaintext"><code>$ brew uninstall openssl --force
</code></pre>
<p>The <code>--force</code> bit will “remove out-of-date keg-only brews as well”
(see the <code>man brew</code> page).</p>
<p>I couldn’t get this to work
unless I updated my
XCode Command Line tools
after upgrading to El Capitan.</p>
<p>So let’s do that:</p>
<pre class="highlight plaintext"><code>$ xcode-select --install
</code></pre>
<p>Be sure to agree to everything,
not just in the dialogue boxes OS X presents,
but in life - just try to say yes more.
(NOTE: Any philosophical disagreements
are beyond the scope of this blog post
and left as an exercise for the reader.)</p>
<p>When that is finished,
then install OpenSSL
and force symlinking
into the appropriate places:</p>
<pre class="highlight plaintext"><code>$ brew update
$ brew install openssl
$ brew link --force openssl
</code></pre>
<p>Now your <code>bundle install</code> should work no problem!</p>
<h3>Acknowledgements</h3>
<p>Thanks to Gabe Berke-Williams for helpful edits.
Read <a href="http://gabebw.com/">his amazing blog</a>
or follow <a href="https://twitter.com/gabebw">his pun-filled Twitter feed</a>
or investigate <a href="https://github.com/gabebw">his myriad of interesting GitHub projects.</a></p>
How to Turn Sales Leads into Awesome Paid Workhttp://adarsh.io/how-to-turn-sales-leads-into-awesome-paid-work2015-11-03T19:00:00-05:002016-09-30T23:10:14-04:00Adarsh Pandit<p>Continuing my series demystifying consulting,
(which premiered <a href="/how-to-run-a-freelance-software-consulting-business">here</a>)
I’m going to share what I know about
closing sales leads.</p>
<h2>Caveat</h2>
<p>As previously stated,
I am not any kind of sales guru
or webinar purveyor.
I’m just a guy who has experience
finding fun freelancing work.</p>
<p>If you want to read the classics on sales,
I honestly can’t help you - I have no idea what they are,
but <a href="http://amzn.to/1Rw38Ne">Amazon</a> probably does.
(Caution: Sales books are also selling you a book
in addition to advice, so be careful)</p>
<p><em>If you haven’t already,
check out
<a href="/how-to-run-a-freelance-software-consulting-business">my original article on how to generate sales leads here</a>.</em></p>
<h2>Okay now I have leads</h2>
<p>Great, so you have a lead!
Wait, what is a “lead” again?</p>
<p>It’s just a person who has showed some interest
in working with you as a consultant.
No one has made any promises,
and sentences end with phrases like
“Let’s see if we can figure this out”.</p>
<p>Everyone is hopeful and excited (probably).
What you do next is critical:
You have a meeting to discuss the project.</p>
<p>You should meet in person if possible.
Remember your goal is to build trust,
the foundation of any good business relationship.</p>
<p>If you can’t do in-person,
videochat to ensure they see
you are a human with a face and feelings.</p>
<h2>The Sales Meeting</h2>
<p>This meeting is a weird one but it doesn’t have to be.
Essentially you’re trying to say
“Hey, I’d like for you to pay me to do stuff. I’m good at what I do.”
and the other party is saying
“Hey, I have no idea who you are,
please prove to me you are good at your job
and that you can help me solve my problem.”</p>
<p>So these are your goals
and those should be plainly stated to everyone
RIGHT AT THE START OF THE MEETING.
Something like:</p>
<blockquote>
<p>“Hey thanks for taking this meeting,
I appreciate your time.
How’s this agenda sound:
1) I get to know you and your problem/project
2) You get to know me and what I’m good at
3) We decide together if there is a fit between the two?”</p>
</blockquote>
<p>The important message you are conveying here is
“I have no idea if it’s a good idea to work together.
We should discuss it and see if that is the case.”</p>
<p>This totally flips people out.
When you are in the Sales Meeting™,
most people expect you to stretch the truth
and be aggressive in pushing your case
because that’s what most people do.</p>
<p>If you start with some practical honesty,
you’ll immediately garner some trust.
Your discussion will go a lot better
when your lead realizes you’re not a greasy weirdo
but just some person looking to find work.</p>
<p>One tip here:
<em>You should get them to talk about their project first.</em>
You are probably good at lots of stuff
and if you go through all of it,
frankly, it will be boring and probably irrelevant.</p>
<p>If you get to hear the project first,
then you can tailor what you share
about your abilities/experience.</p>
<p>If they insist and say “no you first”,
just tell them you want to tailor the discussion
and not waste their time.
If there’s one thing people love,
it’s people not wasting their time.</p>
<h2>Have a pitch of some sort</h2>
<p>When you talk about yourself and your work,
be prepared to show what you’ve done
and talk about who you worked with.</p>
<p>If you’ve signed NDAs,
you should have cleared some anonymized versions of the work
with your previous client before this meeting.</p>
<p>You should also highlight
how you solve problems of this type
and talk about questions that usually come up
when dealing with this kind of work.</p>
<p>You can do this via a portfolio,
or manifesto,
or <a href="http://adarsh.io">blog</a>.</p>
<p>This part of you describing your work
should be prepared, but not rehearsed.</p>
<p>You should practice it 10-15 times on friends
before taking it out on the road for best results.</p>
<p>Also, as you repeat this pitch,
it will evolve and improve over time.
Pay attention to what people respond to
and talk more about those things.</p>
<p>Last note, it should be short, say ~5 minutes.
If there’s one thing people love, it’s people not wasting their time.</p>
<h2>Figure out if there is a fit (AKA “turn down almost all of your leads”)</h2>
<p>Okay, now you’ve heard what they need done
and you have said something about yourself.</p>
<p><strong>At this point, you should probably turn down the work.</strong></p>
<p>In my experience,
you should expect to politely decline about 90% of your leads.</p>
<p>Generally, you shouldn’t have to persuade people.
If the sales process feels like a natural fit
so will the project’s build phase.</p>
<p>What? Aren’t you trying to sell work?</p>
<p>Yes, you are, but odds are,
it’s not a good fit for one of the below-discussed reasons.</p>
<p>But more importantly,
the worse of a fit the project is for you,
the worse it will go
and the lower chance of referrals
which means your reputation and business are sinking.</p>
<p>If you take high-quality good-fit projects,
they will beget more of the same.
If you take crappy death-marches,
you’ll get more of those.</p>
<p>Okay why is it potentially not a good fit?</p>
<ul>
<li>You don’t know how to do what they want</li>
<li>What they want done is probably the wrong way to go about it</li>
</ul>
<p>If it’s the former, you should say something like
“I don’t know how to do that, sorry,” and leave.
If you know someone else who can do the work,
you should offer an introduction
and thank them for making you
a pourover coffee which took 15 minutes.</p>
<p>If you don’t know how to do it
<em>but feel like you could wing it</em>
say that, but then offer a significant discount,
like 50% off for the first few weeks.</p>
<p>If they’re going about things all wrong,
there are two flavors:</p>
<h3>1) This is a terrible project for anyone, anywhere</h3>
<p>You need to cautiously figure out a way to share this
without being a know-it-all. Something like</p>
<blockquote>
<p>Look, clearly you are a sharp lady and know the world of high finance well, but building a mobile app to run hair salons without any experience might be troublesome. As I’ve seen it in my work, some domain expertise is important
to success in software businesses.</p>
</blockquote>
<p>Be sure to explain yourself but also note that you could be totally wrong.
Then, be nice, compliment their carpet, and leave quickly.</p>
<h3>2) This is a reasonable project but some specifics are off</h3>
<p>Maybe you feel like there’s a better way to do this?
You should share that and say why,
ideally sharing some experience where
you did things your way and it turned out amazingly.</p>
<p>This is the best case situation.
You are an expert and will probably do a much better job
than they expected and everyone will be happy.</p>
<p>At this point, you should close the meeting
and say “hey this sounds like it might be a fit”
should we find some more time to go through this in detail?“</p>
<p>The second meeting will be about project specifics
and pricing.</p>
<h2>Negotiating a Contract</h2>
<p>Again, other smarter people than me
have written more on the subject,
but here’s what has worked well for me:</p>
<ul>
<li>Only work on time and materials - never fixed bid.</li>
<li>Set a daily or weekly rate, not an hourly one - it keeps clients from
nitpicking how you spend your time.</li>
<li>Agree to invoice once a week and send them Friday evening when you wrap up for
the day. Be very detailed in accounting for your time in the invoice. I like
<a href="https://adarshpandit.freshbooks.com/tryfreshbooks/www">FreshBooks</a> for invoicing but there are lots of good/simple/free choices.</li>
<li>Make the contract week-to-week with an option to stop with 2 weeks notice. It
allows the project to keep going or stop as needed.</li>
<li>Keep proposals and contracts generic. Don’t specify a ton of low level
requirements to be implemented during the project, because they will change.</li>
<li>Don’t sign NDA’s if possible. No idea is that amazing, it’s execution that
matters. Also, the client won’t tell you <em>anything</em> without an NDA, you should
pass.</li>
<li>Don’t respond to RFPs. It takes forever and is usually a sign the client has
overscoped the project.</li>
<li>Don’t take equity. You are not a seasoned investor. Save your cash and put it
in an index fund.</li>
</ul>
<h2>Closing</h2>
<p>Again, without belaboring the point,
be yourself and don’t force any agreements or partnerships.
The more natural the sales process feels,
the more likely you will have a good outcome,
good referrals,
and booming business.</p>
<p>Please be sure to invite me out on your boat for a ride.</p>
How to Generate Sales Leads as a Freelance Developerhttp://adarsh.io/how-to-generate-sales-leads-as-a-freelance-developer2015-10-30T20:00:00-04:002016-09-30T23:10:14-04:00Adarsh Pandit<p>As I wrote in <a href="/how-to-run-a-freelance-software-consulting-business">this post</a>,
I’m sharing what I know about
consulting in the hope it’s helpful for others.</p>
<p>This post focuses on how to generate sales leads or
“finding people who are interested in paying you.”</p>
<p>Everything here I learned as a freelance
management consultant,
while selling millions of dollars of work
for a medium-sized boutique firm,
and now as a freelance developer.</p>
<h2>Preface</h2>
<p>It’s a weird thing to hire someone else
and pay them for their time.</p>
<p>The relationship requires trust above all else.
Once one party loses trust in the other,
it’s best to move on, re-evaluate what happened,
and find other work.
As such everything you do
needs to be authentic, honest, and professional,
including trying to drum up business.</p>
<p>Also it’s worth noting these tactics work best
when you do them very consistently
for a long time.
There’s no substitute for building good routines
and doing the work.</p>
<p>Finally, it should be noted
that I am by no means perfect at sales
and your mileage may vary.</p>
<p>Okay let’s start:</p>
<h2>Networking</h2>
<h3>Specific Tactics I Use</h3>
<ul>
<li>Keep a list of people to stay in touch with.</li>
<li>Be sure to follow up regularly. Use tools to automate the process.
I like to send a reminder to <a href="http://help.followup.cc/knowledge_base/topics/cheat-sheet"><code>every2months@followup.cc</code></a> with
the subject line “Get Coffee With PERSON” and get reminded regularly.
Repeating calendar invites are great for this as well.</li>
<li>Be Helpful 1: Make introductions on behalf of people you think might
benefit from meeting each other.</li>
<li>Be Helpful 2: Forward articles/videos/tweets/etc to people if you think
they’ll find it interesting / relevant.</li>
<li>Don’t spend time with people you don’t like.</li>
<li>Send them articles when you think they may find them interesting. <a href="/google-reader-as-a-networking-tool">Here’s an
old post where I talk about doing it with Google Reader</a>, which
tells you how old the post is.</li>
</ul>
<p>The goal of these activities
is to make “business friends”
whom you like, and who like you.
If you don’t like someone,
or are just hanging out with them
because you feel you have to,
it won’t work.</p>
<p>You should be helpful to them,
recommending candidates to hire,
articles to read,
people to meet,
and services to try.</p>
<p>You should ask them for advice frequently.
You should ask them for help rarely.
You should support their businesses,
retweet their product announcements,
and support their crowdfunding campaigns,
<em>but only do so because you feel like it</em>.</p>
<p>I should note
that every job I’ve ever gotten
has been a result of networking.
I’m guessing this is broadly true.</p>
<h3>Why Do This</h3>
<p>First of all,
you make business friends to learn.
Asking questions helps you understand
what other companies and situations are like
which helps you handle your own thing.</p>
<p>Second of all, it feels good to help people,
or rather it should.
If it doesn’t,
there’s a whole other set of problems to address.</p>
<p>But really,
the reason you get to know a lot of people
is to be top of mind when they need help.</p>
<p>An example is:
Sally works at a company
and hears
“oh we need to get help with this Rails app,”
and thinks
“I wonder if my friend YOUR_NAME knows someone, or can help…”</p>
<p>Then they call you,
and you have a discussion about how helpful you can be
(if at all).
Be sure to let them know
if you’re the wrong person for the job
but maybe you know who the right person is.</p>
<p>All of this should feel authentic.
If it feels slimy or manipulative to you,
it will seem that way to everyone,
and you won’t build trust (see above).</p>
<h2>Content Marketing: Writing</h2>
<h3>Specific Tactics I Use</h3>
<ul>
<li>Set up a blog which clearly states you are hirable and what skills you have.</li>
<li>Blog and tweet as regularly as you can about your work.
The content should be solid, but quantity and regularity matter much more.</li>
<li>If you do something neat for a client, use their name (with permission).
They may cross-promote your post for you.</li>
<li>Try using an editorial board in Trello to build a pipeline of ideas
which you can push along into posts.</li>
<li>Set regular writing goals like one post per week, one hour a day, etc.</li>
<li>Promote your posts using Twitter, Google+, LinkedIn, Facebook, whatever.
You can use <a href="https://buffer.com">Buffer</a> to automate this stuff.</li>
<li>Find a pal who is good at writing to edit your posts before going out.
I have everything in GitHub and ask for reviews using pull requests.</li>
</ul>
<h3>Why Do This</h3>
<p>Writing blog posts is the highest leverage activity you can engage in.
In other words,
you can reach the most people
per unit time of effort.</p>
<p>Also, posts last forever
and the longer they’re around
the more likely they are to be read.</p>
<p>Finally, your writing is representative of
what you are like to work with.
If it’s clear and well-edited,
it’ll signal how you take care in your work.
If you share interesting perspectives,
it likely means you’ll have valuable things to say
when someone hires you.
If you write very regularly,
it clearly demonstrates discipline.</p>
<h2>Content Marketing: Speaking</h2>
<h3>Specific Tactics I Use</h3>
<ul>
<li>Write a ton of articles. Seriously, as many as you can.</li>
<li>Some of them will get a lot of traction. You’ll know because people will
tweet them and maybe contact you. Analytics could help here also.</li>
<li>Write a 5-10 minute talk about the most popular topic.</li>
<li>Ask to give that talk at a meetup. Organizers are always looking for
good technical material as long as you’re not shamelessly selling something.</li>
<li>Big meetups record or stream the video content. Watch the recording to
see how you did. Also ask others at the meeting for feedback.</li>
<li>Keep giving this talk. In other words, practice.</li>
<li>Expand the talk to something bigger.</li>
<li>Use the expanded talk and video as submission materials for conferences.</li>
<li>Go to conferences and meet all the other nice people.</li>
</ul>
<h3>Why Do This</h3>
<p>Talks help promote your articles, which in turn promote your consulting business.</p>
<p>In addition, speaking publicly makes you seem approachable and gives shy people
a great excuse to talk to you, which is the goal - networking and making
friends in your field of work.</p>
<p>Finally, it’s a lot of fun.</p>
<h2>Then What?</h2>
<p>How do you handle all of this crazy sales demand
now that you are a big shot?</p>
<p>People will find a way to get in touch with you.
You could add an interest form to your blog
to increase the volume,
but note that comes with a decrease in quality.</p>
<p>You may need something like a CRM
if you’re going to run a firm
with other people as employees.</p>
<p>If it’s just you, don’t bother.
Use something like Trello to keep info in one place,
and follow-up regularly with interested parties.</p>
<p>My next post will be on how to actually close these leads.</p>
<p>Thanks to <a href="https://twitter.com/eignerchris">Chris Eigner</a>, <a href="https://twitter.com/gabebw">Gabe Berke-Williams</a>, and <a href="https://twitter.com/captbaritone">Jordan Eldridge</a>
for helpful edits and feedback.</p>