<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Jonathan Johnson's Blog]]></title><description><![CDATA[Thoughts and happenings from a climbing programmer]]></description><link>http://3.89.81.88:80/</link><image><url>http://3.89.81.88:80/favicon.png</url><title>Jonathan Johnson&apos;s Blog</title><link>http://3.89.81.88:80/</link></image><generator>Ghost 3.28</generator><lastBuildDate>Sat, 08 Nov 2025 18:22:05 GMT</lastBuildDate><atom:link href="http://3.89.81.88:80/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[A return to weblogging]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Hello again world, it's been awhile.  Sorry it's been so long since we last talked...</p>
<p>While it <strong>is</strong> true that I've been busy, we both know that's just an excuse.  So much of my early career development centered around blogging, and was spurred by trying to articulately communicate technical ideas.</p>]]></description><link>http://3.89.81.88:80/a-return-to-weblogging/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c4b</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Thu, 15 Aug 2019 22:02:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hello again world, it's been awhile.  Sorry it's been so long since we last talked...</p>
<p>While it <strong>is</strong> true that I've been busy, we both know that's just an excuse.  So much of my early career development centered around blogging, and was spurred by trying to articulately communicate technical ideas.  The practice of self-reflection and thoughtful communication is pivotal in the progression of every software engineer.</p>
<p><strong>So I'm back</strong>, ready to reboot and create a space where I can log lessons learned and battles won.</p>
<p><strong>Let's catch up!</strong>  Since I last blogged...</p>
<ul>
<li>I moved home to Missouri from Colorado 🌄</li>
<li>I spent the last 5 years in remote positions, working on product teams full of smart and talented people 👨🏻‍💻</li>
<li>I lost almost 100 pounds 📉</li>
<li>I went entirely vegan ⓥ</li>
<li>I started rock climbing 🧗🏻‍♂️</li>
<li>I built my <a href="https://packtracker.io/?utm_campaign=links&amp;utm_source=personal&amp;utm_medium=a-return-to-weblogging">own little product for webpack users</a> 📊</li>
<li>I <a href="https://www.youtube.com/watch?v=VO2CnXaH4Jc">spoke at a conference</a> 🎤</li>
<li>I bought 10 acres of woods 🌳🌲🌲🌳🌲</li>
<li>I traveled to 6 different countries 🇨🇦🇵🇹🇮🇪🇪🇸🇫🇷🇨🇿</li>
</ul>
<p>I've got quite the backlog of experiences to write about, and I've also decided to bring along the <strong>least egregious</strong> and evergreen posts from my pre-2015 self.</p>
<p>Apologies for the young opinions and PHP 😂</p>
<p>Hopefully it won't be so long until you see another post from me.</p>
<p>Cheers!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Why callback hell can be your friend.]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>We're all too familiar with this term and stigma.  I have enjoyed my limited time working with node.js professionally, but I can't have a conversation with someone outside the ecosystem without callback hell coming up.</p>
<p>The idea is simple.  With JavaScript, it is canonical to handle all I/O</p>]]></description><link>http://3.89.81.88:80/why-callback-hell-can-be-your-friend/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c55</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Tue, 06 Jan 2015 17:02:44 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>We're all too familiar with this term and stigma.  I have enjoyed my limited time working with node.js professionally, but I can't have a conversation with someone outside the ecosystem without callback hell coming up.</p>
<p>The idea is simple.  With JavaScript, it is canonical to handle all I/O in an asynchronous way.  The lowest level tool being callbacks passed to functions that perform I/O.</p>
<p>So routinely, we get an arbitrary example that looks something like this...</p>
<pre><code class="language-javascript">DBfind(function(err, thing) {
    thing.doSomething(function(err) {
        thing.doAnother(function(err) {
            thing.doYetAnother(function(err) {
                // :(((((
            });
        });
    });
});
</code></pre>
<p>The primary problem presented with these types of examples boils down to the fact that <strong>it is ugly</strong>.<sup><a href="#foot1">1</a></sup>  With the universal counter point, Promises or flow control libraries, focused on fixing nesting depth.</p>
<p>Is that the <strong>primary</strong> problem though, or is it deeper?</p>
<p>We have stacked 4 sequential I/O operations.  Is this a good thing even in a synchronous I/O environment?  Imagine the same logic stuffed into an object method that blocks awaiting the return.  On platforms that prefer synchronous I/O, these expensive operations are <strong>easy to bury</strong>.</p>
<p>The concept of <strong>callback hell</strong> should be treated <strong>first</strong> as a symptom that <em>could</em> point to a deeper design issue.  Is this method's single responsibility I/O?  I have come to view methods accepting callbacks as a potential code smell.  Causing us to determine whether the I/O can be made more explicit to the developer.</p>
<p>A common offense being what I will call tail call I/O.  The object method mutates the object, and then calls out to I/O proxying the callback passed to the original method call.</p>
<p>Imagine the following example.</p>
<pre><code class="language-javascript">Thing.prototype.updateFoo = function(newFoo, callback) {
    this.somethingComplicated = newFoo;
    this.save(callback);
};

Thing.prototype.updateBar = function(newBar, callback) {
    this.somethingMoreComplicated = newBar;
    this.save(callback);
};

var thing = new Thing();

thing.updateFoo('Foo', function(err) {
    thing.updateBar('Bar', function(err) {
        // :((((((
    };
};
</code></pre>
<p>In these cases, you can easily flatten that out like so.</p>
<pre><code class="language-javascript">Thing.prototype.updateFoo = function(newFoo) {
    this.somethingComplicated = newFoo;
};

Thing.prototype.updateBar = function(newBar) {
    this.somethingMoreComplicated = newBar;
};

var someThing = new Thing();
someThing.updateFoo('Foo');
someThing.updateBar('Bar');
someThing.save(function(err) {
    // :)
});
</code></pre>
<p>Not only is this nicer, but more importantly <strong>it is a design improvement</strong>.  Reaching out to I/O land only once, when the developer consciously decides it is required.  This approach also makes <code>.updateFoo()</code> and <code>.updateBar()</code> <strong>easy</strong> to test. Previously, they would be beholden to the external services performing the I/O operation, needing to be mocked or integrated into the test runner.</p>
<p>There are situations that require a waterfall of I/O operations, but our first instinct should not be to accept them as is, targeting cosmetic defects.</p>
<p>Instead of bemoaning this distinctive property of JavaScript and slapping some paint on it, use it to better assess the quality and performance of our api designs.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Keeping it local with npm]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In transitioning to the Node ecosystem, I quickly recognized many strengths npm brings to the table as a package manager.  As someone who has used rvm/bundler to routinely manage gemsets, an immediate win I noticed was how every install of a project is localized within the project <strong>by default</strong></p>]]></description><link>http://3.89.81.88:80/keeping-it-local-with-npm-scripts/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c53</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Tue, 18 Nov 2014 18:00:34 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In transitioning to the Node ecosystem, I quickly recognized many strengths npm brings to the table as a package manager.  As someone who has used rvm/bundler to routinely manage gemsets, an immediate win I noticed was how every install of a project is localized within the project <strong>by default</strong>.</p>
<blockquote class="twitter-tweet tw-align-center" lang="en"><p>Really enjoying the <a href="https://twitter.com/hashtag/node?src=hash">#node</a> package ecosystem… everything is local by default. Global packages being mere convenience.</p>&mdash; Jonathan Ⓓ Johnson (@jondavidjohn) <a href="https://twitter.com/jondavidjohn/status/442411508228575232">March 8, 2014</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>This is not only true about code level library dependencies, but also command line tooling that the project may rely on for automation.  These tools are linked into <code>./node_modules/.bin/*</code></p>
<p>For example, after an <code>npm install</code> of a project that declares gulp (a popular task runner) as a <code>devDependency</code>, you would get your task runner installed at <code>./node_modules/.bin/gulp</code>.  This means you don't actually have to install gulp globally as long as you're ok with running gulp with</p>
<pre><code>./node_modules/.bin/gulp &lt;task&gt;
</code></pre>
<p>Because this is a bit verbose, most projects also recommend you install a global gulp runner that enables you to shorten this up with a familiar</p>
<pre><code>gulp &lt;task&gt;
</code></pre>
<p>But are these global installs necessary to reap the more succinct benifit?</p>
<p>This is where npm's script feature comes in.</p>
<h3 id="npmscripts">npm scripts</h3>
<p>Another feature of npm is the ability to define both <a href="https://docs.npmjs.com/misc/scripts">lifecycle tasks for your package</a> and <a href="https://docs.npmjs.com/cli/run-script">custom package scripts</a>, giving it some limited ability as a task runner itself.</p>
<p><img src="http://3.89.81.88/assets/images/2014/11/eb47z.jpg" alt></p>
<p>In your <code>package.json</code> you can define these scripts like so.</p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;my_package&quot;,
  &quot;version&quot;: &quot;0.0.1&quot;,
  &quot;description&quot;: &quot;My Awesome Project.&quot;,
  &quot;scripts&quot;: {
    &quot;&lt;task&gt;&quot;: &quot;gulp &lt;task&gt;&quot;
  }
}
</code></pre>
<p>Then you can</p>
<pre><code>npm run &lt;task&gt;
</code></pre>
<p>Which achieves our succinct interface while divorcing the global install requirement.</p>
<p>This is possible because <code>npm run &lt;...&gt;</code> runs with <code>./node_modules/.bin</code> included in its path.</p>
<h3 id="consitency">consitency</h3>
<p>Another benifit of this approach is having a consistent task interface across multiple projects that might have differing task running needs.  One project might particularly benifit from a stream based task runner like gulp, while another might not need an additional task runner at all.</p>
<p>Both projects in this case would use the same npm scripts interface and would be immediately familiar for team members that might not be familiar with one or both projects.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Generate test functions using the RegExp prototype.]]></title><description><![CDATA[<!--kg-card-begin: markdown--><pre><code class="language-javascript">  var testForA = RegExp.prototype.test.bind(/[aA]/);
  // function () { [native code] }

  testForA('hello');
  // false

  testForA('hella');
  // true

  ['hello', 'hella', 'holla'].filter(testForA);
  // ['hella', 'holla']
</code></pre>
<p>Oh the lengths we'll go to avoid typing 'function'</p>
<!--kg-card-end: markdown-->]]></description><link>http://3.89.81.88:80/using-the-regexp-prototype-as-a-generator/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c50</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Fri, 10 Oct 2014 18:12:30 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><pre><code class="language-javascript">  var testForA = RegExp.prototype.test.bind(/[aA]/);
  // function () { [native code] }

  testForA('hello');
  // false

  testForA('hella');
  // true

  ['hello', 'hella', 'holla'].filter(testForA);
  // ['hella', 'holla']
</code></pre>
<p>Oh the lengths we'll go to avoid typing 'function'</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[NodeJS is Human]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Node is much more than <strong>JavaScript on the Server</strong>.</p>
<p>That's Node's <strong>gimmick</strong> though right?  You can now write both your server and client in JavaScript.</p>
<p>No longer will you toil away, learning and bouncing between multiple environments.  Painfully switching contexts, excreting blood and tears when you are forced to move</p>]]></description><link>http://3.89.81.88:80/nodejs-is-human/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c49</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Wed, 16 Apr 2014 16:44:26 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Node is much more than <strong>JavaScript on the Server</strong>.</p>
<p>That's Node's <strong>gimmick</strong> though right?  You can now write both your server and client in JavaScript.</p>
<p>No longer will you toil away, learning and bouncing between multiple environments.  Painfully switching contexts, excreting blood and tears when you are forced to move from the client to the server or vice versa.</p>
<p>Hopefully you picked up on my sarcasm.</p>
<p>The fact that Node uses JavaScript is <strong>but a tertiary point</strong> (a benefit to some, a downside to others).  It most definitely is a contributor to it's success, but so much so that the primary point and purpose of Node is often missed.  If this is obvious and apparent to you, you probably can stop reading.</p>
<p>Saying that you like Node because you can write JavaScript on the server side is like saying you like red <a href="http://en.wikipedia.org/wiki/Lotus_Elise">Lotus Elises</a> because they are painted red.  Not everyone likes red, and even if everyone did, it's hardly the most important/objective thing that makes this car &quot;good&quot;.</p>
<p><strong>Node is fundamentally different</strong> than the dynamic language platform status quo.  It was born from an obsession with efficiency.  A dissatisfaction with the classic 1-to-1 relationship between threads and connections drove it's ability to handle a significantly increased level of concurrency <strong>for web applications written with dynamic languages</strong>.</p>
<h2 id="blockingandtheioproblem">Blocking and the I/O Problem</h2>
<p>The classic <a href="http://en.wikipedia.org/wiki/Bottleneck">bottleneck</a> of most applications, web or otherwise, is <strong><a href="http://en.wikipedia.org/wiki/Input/output">I/O</a></strong>.</p>
<p>The application is regularly transferring information to and from a database, the file system, the network, or a combination of these. Generally, the transfer of this information is far slower than the speed of the CPU operating on this information in memory.  <strong>Productive</strong> CPU over-utilization is likely not your problem.</p>
<p>The second problem is the way we have handled the first.  Historically understanding computers, we think sequentially.  This is how Computers think right?  You provide a set of instructions and they are run in sequence from top to bottom.  Your first program generally looks something like this.</p>
<pre><code class="language-javascript">// print
console.log(&quot;Enter your name: &quot;);

// block execution to retrieve data
// keeping the process tied up awaiting the
// data's return
var name = console.read();

// manipulate data and report
console.log(&quot;Hello &quot; + name + &quot;!&quot;);
</code></pre>
<p>But what if you could do this in a <strong><em>non</em>-blocking</strong> way</p>
<pre><code class="language-javascript">// print
console.log(&quot;Enter your name: &quot;);

// make a request for the data, but allow the process to
// be free to do other things, providing a bit of code
// to run when the data is retrieved.
console.read(

  // When we are notified we have a
  // response, manipulate data and report
  function(err, name) {
    console.log(&quot;Hello &quot; + name + &quot;!&quot;);
  }
);
</code></pre>
<p>Making your process block and wait around for millions of clock cycles is a waste of time and resources.  To handle additional requests, you must use a process manager of some kind to keep around multiple processes.  As the web moves to be a more interactive medium, we are continually reducing the size of each request, while multiplying the number of requests generated by every single client.  This makes it obvious why the 1-to-1 relationship between a request and a process is hard to scale.</p>
<p>Historically, we have taught ourselves to more easily reason our programs in the first style, but I would argue that the second style is equally, if not more, intuitive as a human being.</p>
<h3 id="thinkinglikeahuman">Thinking like a Human</h3>
<p>As a human being you understand the asynchronous nature of information flow.  You intuitively know that it's just not efficient or practical to stop everything you are doing every time you need to retrieve or communicate information.</p>
<p>As a developer, every time you ask a manager or stake holder of a project for clarification, do you simply sit and wait quietly for a reply?  <strong>No</strong>, of course you don't.  You move on to the next thing that you can make progress with, juggling a hand full of important tasks.  Once the information comes back, you continue with the related task.</p>
<p>For a more rudimentary anecdote, you are driving in your car with a friend of yours and you need to know the weather report for tomorrow.  <strong>Would you slam on the breaks and stop traffic to turn to your friend and ask what the weather will be like tomorrow?</strong>  Waiting still and silent (except for the honking behind you) until he looks it up for you?  <strong>Of course you wouldn't</strong>, you would continue having other conversations and driving while he retrieves the information for you.</p>
<p>In this way, Node's non-blocking/asynchronous model does not need to be as foreign as it would seem at first pass.</p>
<h2 id="whynotthreads">Why not threads?</h2>
<p><strong>Threads are hard, heavy, and generally overkill</strong></p>
<p>They do solve the rudimentary problem of parallelism, but they present an all new set of problems around thread-safety and mutability.  They are generally very complex and difficult for dynamic languages to implement, if implemented at all.</p>
<blockquote>
<p>In Node, everything <strong>but</strong> your code, runs in parallel.</p>
</blockquote>
<p>Everything that can be handled via parallelism for you, <strong>is</strong>.  But because <strong>your code</strong> is never run in parallel and always in a single thread, issues of thread-safety and mutability fall away.  This provides many of the benefits of parallelism for the common use case without presenting the developer with near the additional complexity.</p>
<p>Again, I would argue that the way Node handles parallelism again mirrors how we as humans process thoughts, not in parallel, but with highly efficient multi-tasking.</p>
<h2 id="languagexhasanonblockingservertoo">Language X has a non-blocking server too...</h2>
<p>Non-blocking I/O is not a new thing, but what makes Node different is the platform is built entirely around this principle.  Non-blocking is philosophically adopted as <strong>the rule, not the exception.</strong>  So when you go to grab that Node MySQL library, you can expect it will be fully compatible with your non-blocking application.  Generally this <strong>cannot</strong> be said of other event driven frameworks written in other dynamic languages.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Extending JavaScript Functions]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<p>DISCLAIMER: This is actually a really terrible idea, and mostly just a thought experiment!</p>
</blockquote>
<p>This is a pattern you can use to extend JavaScript Functions, <strong>including native functions</strong>.</p>
<p>For example, we’ll extend the <code>join()</code> function of the <code>Array</code> type and add some logging before passing control back to the</p>]]></description><link>http://3.89.81.88:80/extend-javascript-functions/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c4a</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Sat, 22 Feb 2014 18:43:31 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<p>DISCLAIMER: This is actually a really terrible idea, and mostly just a thought experiment!</p>
</blockquote>
<p>This is a pattern you can use to extend JavaScript Functions, <strong>including native functions</strong>.</p>
<p>For example, we’ll extend the <code>join()</code> function of the <code>Array</code> type and add some logging before passing control back to the native <code>join()</code> function.</p>
<pre><code class="language-javascript">Array.prototype.join = (function(_super) {

    // return our new `join()` function
    return function() {
        console.log(&quot;Hey, you called join!&quot;);
        return _super.apply(this, arguments);
    };         // Pass control back to the original join()
               // by using .apply on `_super`

})(Array.prototype.join);
//                            
// Pass the original function into our
// immediately invoked function as `_super`
// which remains available to our new
// function thanks to JavaScript closures.
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Git alias with parameters]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>You can form more complex and useful git aliases when you realize you can write aliases like you would write a standard shell function.  Prepending your alias with an exclamation mark tells git to expand the alias to your shell, enabling the use of standard unix tools to do some</p>]]></description><link>http://3.89.81.88:80/git-aliases-parameters/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c4f</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Fri, 23 Aug 2013 21:48:52 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>You can form more complex and useful git aliases when you realize you can write aliases like you would write a standard shell function.  Prepending your alias with an exclamation mark tells git to expand the alias to your shell, enabling the use of standard unix tools to do some fun things.</p>
<p><strong>Simple Example</strong></p>
<pre><code>[alias]
    ...
    sayhello = !(echo &quot;Hello World&quot;)
    ...
</code></pre>
<p>This shows you how to run a simple single line bash command as a git alias.  You first tell git you are going to run a shell command with !() then you give it your single line of bash.</p>
<h2 id="multilinealiasesandpassingparameters">Multi line aliases and passing parameters</h2>
<p>The next step is to be able to run more of a shell script.  Multiple lines and be able to pass in arguments.</p>
<pre><code>[alias]
    ...
    say = &quot;!f() { msg=${1-Hello World}; echo $msg;  }; f&quot;
    ...
</code></pre>
<p>This illustrates the structure of a basic shell script git alias that allows for multiple lines and arguments.  You first tell git you are going to run a shell command with <code>!</code>, then you define a shell function named <code>f</code> with <code>f(){ };</code>, then run it with <code>f;</code>.  This enables you to accept arguments into your functions like <code>$1</code> in our case.</p>
<p>Also, in case you are wondering, <code>${1-Hello World}</code> assigns <code>&quot;Hello World&quot;</code> to <code>$msg</code> if no value is present in <code>$1</code> which is how I chose to provide a default value.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Continued quest for the perfect git bash prompt.]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>On the heels of my <a href="http://jondavidjohn.com/a-responsive-bash-prompt">responsive bash prompt</a>, I've made another few moves to bring more utility to my git bash prompt.</p>
<h2 id="dirty">Dirty?</h2>
<p>Yes, so we have our git branch showing in our bash prompt as most do these days.  That's a really helpful piece of information to be readily</p>]]></description><link>http://3.89.81.88:80/quest-for-the-perfect-git-bash-prompt-redux/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c54</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Thu, 08 Aug 2013 03:37:52 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>On the heels of my <a href="http://jondavidjohn.com/a-responsive-bash-prompt">responsive bash prompt</a>, I've made another few moves to bring more utility to my git bash prompt.</p>
<h2 id="dirty">Dirty?</h2>
<p>Yes, so we have our git branch showing in our bash prompt as most do these days.  That's a really helpful piece of information to be readily available, but lets do more.</p>
<p>I wanted the name of my branch to also let me know if my working directory is clean or not.  If I have uncommitted changes or untracked files, I want to be able to know that just by looking at my bash prompt.  So I've now made it so the branch name is red when the working tree is dirty and green when it's clean.</p>
<p><img src="http://3.89.81.88/assets/images/2014/Feb/2013_08_07_at_9_14_PM.png" alt></p>
<p><a href="https://github.com/jondavidjohn/dotfiles/blob/aad34fe2b41d12d7796f7c0deb8ecf8296015e6e/general/.bash_profile#L55-L61">Here's how.</a></p>
<h2 id="outofsync">Out of Sync?</h2>
<p>How many times have you committed changes and forgotten to push them?  Or been working away on a feature and didn't notice you were behind by a number of commits?  Wouldn't it be nice to also know if you're ahead or behind the remote tracking branch at a glance?</p>
<p>Here's what I've got</p>
<p><img src="http://3.89.81.88/assets/images/2014/Feb/aheadbehind.jpg" alt></p>
<p><a href="https://github.com/jondavidjohn/dotfiles/blob/aad34fe2b41d12d7796f7c0deb8ecf8296015e6e/general/.bash_profile#L101-L121">Here's how I did it</a></p>
<p>All of these tweaks and modifications are tracked in <a href="https://github.com/jondavidjohn/dotfiles">my dotfiles repository</a> so take a look.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Where a polyglot mindset goes awry.]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>A commitment to polyglot mindset was an intentional decision I made early in my career as a developer.</p>
<p>(so, earlier than <strong>now</strong>...)</p>
<p>What did this mean at the time?</p>
<blockquote>
<p>I'm going to know all the languages, so when a problem arises that needs solving, I'll solve it with the most</p></blockquote>]]></description><link>http://3.89.81.88:80/where-polyglot-programming-goes-awry/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c4c</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Thu, 02 May 2013 17:43:13 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>A commitment to polyglot mindset was an intentional decision I made early in my career as a developer.</p>
<p>(so, earlier than <strong>now</strong>...)</p>
<p>What did this mean at the time?</p>
<blockquote>
<p>I'm going to know all the languages, so when a problem arises that needs solving, I'll solve it with the most perfect (obscure) technology choice.  Achieving a solution with the clearest and correctest code base.</p>
</blockquote>
<p>During my last round of job interviews, I can hear myself speaking like this.  I can just hear &quot;the right tool for the job&quot; rolling off my tongue.</p>
<p>Maybe it's just me, but this seems like pervasive wisdom propagating through our industry right now, especially to new comers in the field.  That it's important to know a lot of languages and technologies so that you can use the <strong>best</strong> of all the things, to solve problems perfectly.</p>
<h2 id="thepolyglotmindset">The Polyglot Mindset</h2>
<p>Sometimes this mantra can easily reek of our generations fear of commitment.  Jumping from language to language, framework to framework.</p>
<blockquote>
<p>I wrote a rails app, therefore I know rails.</p>
</blockquote>
<blockquote>
<p>I wrote a node app, therefore I know node.</p>
</blockquote>
<blockquote>
<p>I wrote a python script, therefore I know python.</p>
</blockquote>
<p>This sort of aggressive polyglot mindset is like a boy scout in search of merit badges.  A classic jack of all trades, and a master of none.</p>
<p>The little bit of experience I've gained has shown me that while it's good to be comfortable learning new things, it's far more valuable to gain mastery in a few things.  To spend a significant amount of time with a single technology, or family of technologies.  Learn the quirks and demystify the magic.  To not be satisfied by breadth, but to <strong>seek out depth</strong>.</p>
<h2 id="therighttoolforthejob">&quot;The right tool for the job&quot;</h2>
<p>I've also learned that &quot;the right tool for the job&quot; seldom exists, and when it does it slaps you so hard in the face you cannot ignore its existence.</p>
<p>The truth (and beauty) of our field is that you can solve the same problem 10 different ways.</p>
<p>Within any successful organization there is a core technology focus, and it's highly likely that 1 of the 10 possible solutions involves a technology everyone on the team is familiar with.  As much as &quot;the right tool for the job&quot; is a unicorn, as is a master of all trades, let alone a team of them.</p>
<p>What happens when you (are allowed to) choose a technology that you know (dabbled in), and the <em>perfect solution</em> starts breaking?</p>
<p>You go find the resident expert on ... oh wait... <strong>you</strong> are the resident expert.</p>
<p>There are many places in life where the theoretical world and the real world clash so harshly.  This is one of those places.  <strong>This is one of those fields.</strong></p>
<p>This resounds so clearly in the talk I posted recently about <a href="http://www.infoq.com/presentations/Pinterest">Scaling Pintrest</a> .  In which the overarching lesson learned is that a simplified, familiar, mature architecture will likely be more resilient and maintainable, than one that contains a grab bag of the latest and greatest (immature and unfamiliar) solutions.</p>
<h2 id="sobeignorantofothertechnologies">So be ignorant of other technologies?</h2>
<p>Having said all this I still believe <s>in a polyglot mindset</s> that a polyglot mindset is useful in its place.</p>
<p>Running with weekend projects in foreign languages teaches you a lot.  Not just about the technology in use, but it breaks you out of the logical <s>rut</s> path your everyday technology ingrains in you.  You will begin to use your everyday technologies in ways you hadn't yet thought of.</p>
<p>Gain exposure to general programming idioms and patterns that you wouldn't otherwise be exposed to.  Learn new ways to solve problems with your everyday language by learning the idioms of others.</p>
<p>Enjoy the new, but remember to <strong>respect mastery, familiarity, and maturity</strong>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Clojure threading macros in JavaScript]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>The <a href="http://clojuredocs.org/clojure_core/clojure.core/-%3E%3E">thread-first</a> and <a href="http://clojuredocs.org/clojure_core/clojure.core/-%3E">thread-last</a> clojure threading macros are a really neat feature of Clojure, and somewhat difficult to explain to someone who has never had a use for them.</p>
<p>These two tools enable you to unwrap deeply nested function calls in a more readable way, without creating a bunch of</p>]]></description><link>http://3.89.81.88:80/clojure-threading-macros-in-javascript/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c47</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Thu, 28 Feb 2013 17:07:40 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>The <a href="http://clojuredocs.org/clojure_core/clojure.core/-%3E%3E">thread-first</a> and <a href="http://clojuredocs.org/clojure_core/clojure.core/-%3E">thread-last</a> clojure threading macros are a really neat feature of Clojure, and somewhat difficult to explain to someone who has never had a use for them.</p>
<p>These two tools enable you to unwrap deeply nested function calls in a more readable way, without creating a bunch of single use variables in the process.</p>
<p>I'm going to create a few functions to make this seem more useful...</p>
<pre><code class="language-js">function sum(a, b) { return a + b; }
function diff(a, b) { return a - b; }
function str(a) { return a + &quot;&quot;; }
</code></pre>
<p>Consider this</p>
<pre><code class="language-js">var result = str(diff(10, sum(3, parseInt(&quot;3&quot;)))); // &quot;4&quot;
</code></pre>
<p>We <em>could</em> make it a bit more clear like this</p>
<pre><code class="language-js">var inted  = parseInt(&quot;3&quot;);
var sumed  = sum(3, inted);
var diffed = diff(10, sumed);
var result  = str(diffed); // &quot;4&quot;
</code></pre>
<p>But what if we could thread the values through like this? (<code>-&gt;&gt;</code> is the thread-last operator in Clojure)</p>
<pre><code class="language-js">var result = thread(&quot;-&gt;&gt;&quot;, &quot;3&quot;
                           parseInt,
                           [sum, 3],
                           [diff, 10],
                           str); // &quot;4&quot;
</code></pre>
<p>Looking at this you can start to see what the thread-<strong>last</strong> macro does.  It starts with the value <code>&quot;3&quot;</code> and passes it as the <strong>last</strong> argument to <code>parseInt()</code>.  The result of that, gets passed as the last argument to <code>sum()</code> (with 3 being the first argument). this goes on and on until the last function returns the result.</p>
<p>You can imagine what the thread-<strong>first</strong> macro (<code>-&gt;</code>) does...</p>
<pre><code class="language-js">var result = thread(&quot;-&gt;&quot;, &quot;3&quot;
                          parseInt,
                          [sum, 3],
                          [diff, 10],
                          str); // &quot;-6&quot;
</code></pre>
<p>The only call that changes result is <code>diff()</code> because with the thread-<strong>first</strong> macro, the result is passed as the <strong>first</strong> argument. Diff becomes <code>diff(6, 10)</code>.</p>
<p>Here is my implementation of these Clojure threading macros in Javascript.</p>
<pre><code class="language-js">var thread = function() {
    var i, type, func, value;
    var args = Array.prototype.slice.call(arguments);

    type = args.shift();
    value = args.shift();

    switch (type) {
        case '-&gt;;': // thread-first
            while (args.length) {
                arg = args.shift();
                if (arg instanceof Array) {
                    func = arg.shift();
                    arg.unshift(value);
                    value = func.apply(this, arg);
                }
                else {
                    value = arg(value);
                }
            }
            break;

        case '-&gt;&gt;': // thread-last
            while (args.length) {
                arg = args.shift();
                if (arg instanceof Array) {
                    func = arg.shift();
                    arg.push(value);
                    value = func.apply(this, arg);
                }
                else {
                    value = arg(value);
                }
            }
            break;
    }
    return value;
};
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[You are not your code]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><a href="http://sstephenson.us/posts/you-are-not-your-code">You are not your code</a></p>
<blockquote>
<p>But this process is how we move the shared infrastructure forward. In order to advance the state of the art, we have to be willing not only to try new ideas, but to retreat when those ideas prove untenable or when something better comes along.</p></blockquote>]]></description><link>http://3.89.81.88:80/you-are-not-your-code/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c56</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Fri, 14 Dec 2012 17:29:22 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><a href="http://sstephenson.us/posts/you-are-not-your-code">You are not your code</a></p>
<blockquote>
<p>But this process is how we move the shared infrastructure forward. In order to advance the state of the art, we have to be willing not only to try new ideas, but to retreat when those ideas prove untenable or when something better comes along. And we have to be able to speak candidly about problematic code without fear of offending the egos behind it.</p>
</blockquote>
<p>Software Engineering is an interesting art, one in which you pour over the smallest details of something that you are crafting into existence, but optimally are detached from the work as if you didn't.  It's a very tricky balance to strike, and one that I believe comes with time and experience.  Time and experience that will continue to show you that the beautiful solution you create today will be flawed and ugly by the standards 6 months or a year (if you are lucky) in the future.</p>
<p>I think there is a second lesson here, one that comes from the other side of the equation.  Learning how to critique and question the work of others.</p>
<p>Just as you are not your code, remember that <strong>they are not their code</strong>.</p>
<p>Always seek to build up in collaboration instead of attacking in competition.  The enlightened solution you provide today will be the next subject of critique.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[A "responsive" bash prompt]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<p><strong>UPDATE:</strong> I've moved this code into <a href="https://github.com/jondavidjohn/dotfiles">my dotfiles repo</a> as I continue to improve and update it.</p>
</blockquote>
<!--kg-card-end: markdown-->]]></description><link>http://3.89.81.88:80/a-responsive-bash-prompt/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c57</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Mon, 03 Dec 2012 16:57:24 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<p><strong>UPDATE:</strong> I've moved this code into <a href="https://github.com/jondavidjohn/dotfiles">my dotfiles repo</a> as I continue to improve and update it.</p>
</blockquote>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Show private and protected PHP members with json_encode]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="theproblem">The Problem</h2>
<p>This may be news to some, but <code>json_encode()</code> respects property visibility.</p>
<p>Meaning that if you have a class that looks like this...</p>
<pre><code class="language-php">class Thing {

    public $something;
    protected $protected_something;
    private $private_something;

    public __construct($pub, $prot, $priv) {
        $this-&gt;something = $pub;
        $this-&gt;protected_something = $prot;
        $this-&</code></pre>]]></description><link>http://3.89.81.88:80/show-non-public-members-with-json_encode/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c52</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Wed, 24 Oct 2012 18:20:24 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="theproblem">The Problem</h2>
<p>This may be news to some, but <code>json_encode()</code> respects property visibility.</p>
<p>Meaning that if you have a class that looks like this...</p>
<pre><code class="language-php">class Thing {

    public $something;
    protected $protected_something;
    private $private_something;

    public __construct($pub, $prot, $priv) {
        $this-&gt;something = $pub;
        $this-&gt;protected_something = $prot;
        $this-&gt;private_something = $priv;
    }

    public get_private() {
        return $this-&gt;private_something;
    }

    public get_proctected() {
        return $this-&gt;protected_something;
    }
}
</code></pre>
<p>And you run one of these guys through <code>json_encode()</code></p>
<pre><code class="language-php">$thing = new Thing(&quot;One&quot;, &quot;Two&quot;, &quot;Three&quot;);
echo json_encode($thing);
</code></pre>
<p>You'll end up with the following</p>
<pre><code class="language-json">{
    &quot;something&quot;: &quot;One&quot;
}
</code></pre>
<p><code>json_encode()</code> only serializes the publicly visible properties of an object.  If you follow the getter/setter pattern (<a href="http://www.adam-bien.com/roller/abien/entry/encapsulation_violation_with_getters_and">which I don't particularly recommend</a>), this can be a neusense.</p>
<h2 id="php540">PHP &lt; 5.4.0</h2>
<p>The solution to this problem for those running PHP 5.3 or less (most of us), is to implement a json encoding function within your class.  Which gives all your properties the visibility they need, and allows you to control the exact json representation of your object.</p>
<p>Using the example class above...</p>
<pre><code class="language-php">class Thing {

    ...
    public function to_json() {
        return json_encode(array(
            'something' =&gt; $this-&gt;something,
            'protected' =&gt; $this-&gt;get_protected(),
            'private' =&gt; $this-&gt;get_private()
        ));
    }
    ...
}
</code></pre>
<p>Now, you'll generate the json representation with your method (which uses <code>json_encode()</code> internally)...</p>
<pre><code class="language-php">$thing = new Thing(&quot;One&quot;, &quot;Two&quot;, &quot;Three&quot;);
echo $thing-&gt;to_json();
</code></pre>
<p>You'll end up with the following</p>
<pre><code class="language-javascript">{
    &quot;something&quot;: &quot;One&quot;,
    &quot;protected&quot;: &quot;Two&quot;,
    &quot;private&quot;: &quot;Three&quot;
}
</code></pre>
<h2 id="php540">PHP &gt;= 5.4.0</h2>
<p>For all you lucky ones out there working in a PHP 5.4 environment, your solution is a bit more elegant</p>
<p>Simply <code>implement</code> the <code>JsonSerializable</code> interface and add the <code>jsonSerialize</code> function which should return the data structure you want to be represented in JSON.</p>
<p>Using the example class above...</p>
<pre><code class="language-php">class Thing implements JsonSerializable {

    ...
    public function jsonSerialize() {
        return [
            'something' =&gt; $this-&amp;gt;something,
            'protected' =&gt; $this-&amp;gt;get_protected(),
            'private' =&gt; $this-&amp;gt;get_private()
        ];
    }
    ...
}
</code></pre>
<p>Now, when you run one of these guys through <code>json_encode()</code></p>
<pre><code class="language-php">$thing = new Thing(&quot;One&quot;, &quot;Two&quot;, &quot;Three&quot;);
echo json_encode($thing);
</code></pre>
<p>You'll end up with the following</p>
<pre><code class="language-javascript">{
    &quot;something&quot;: &quot;One&quot;,
    &quot;protected&quot;: &quot;Two&quot;,
    &quot;private&quot;: &quot;Three&quot;
}
</code></pre>
<p>This is the preferable solution, because now you don't have to write documentation for the users of your library/code how to convert your object to JSON, they simply use the native PHP JSON API.</p>
<h2 id="bonusiwanttojustencodeeveryproperty">Bonus: I want to just encode EVERY property</h2>
<p>Just loop over the object inside any of the json methods above...</p>
<pre><code class="language-php">...
    $json = array();
    foreach($this as $key =&gt; $value) {
        $json[$key] = $value;
    }
    return $json; // or json_encode($json)
...
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Git pull from a PHP script, not so simple.]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I intended to set up a repository (hosted on BitBucket) to initiate a pull on a dev server when new commits are pushed up.</p>
<p>It seemed like a simple enough process.  BitBucket has a service that will fire off a POST request as a post-receive hook.  So I set up</p>]]></description><link>http://3.89.81.88:80/git-pull-from-a-php-script-not-so-simple/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c58</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Fri, 05 Oct 2012 21:39:12 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I intended to set up a repository (hosted on BitBucket) to initiate a pull on a dev server when new commits are pushed up.</p>
<p>It seemed like a simple enough process.  BitBucket has a service that will fire off a POST request as a post-receive hook.  So I set up a receiving php script to check a randomized token and then initiate the <code>git pull</code>.  Looking something like this...</p>
<pre><code class="language-php">define('PRIVATE_KEY', 'XXXXXXXXXXXXXXXXxxx');

if ($_SERVER['REQUEST_METHOD'] === 'POST'
        &amp;&amp; $_REQUEST['thing'] === PRIVATE_KEY)
{
    echo shell_exec(&quot;git pull&quot;);
}
</code></pre>
<p>Didn't end up being as simple as I had anticipated...</p>
<p>There were a few considerations that I did not take into account.  Documenting them here will hopefully help you avoid some obstacles in trying to get something like this set up.</p>
<h2 id="thebinaryandthepath">the binary and the $PATH</h2>
<p>The user that is attempting to execute <code>git pull</code> is the apache user (<code>www</code> in our case).  This user did not happen to have <code>git</code> in their path.</p>
<p>This took a while to track down because the <code>exec()</code> family of functions simply fail silently because they only report <code>STDOUT</code> and not <code>STDERR</code>.  To get the function to report <code>STDERR</code> you can route it into <code>STDOUT</code> by adding <code>2&gt;&amp;1</code> at the end of your command.</p>
<p>After I realized this I logged in and found the full path of the git binary with <code>which git</code>, which is <code>/full/path/to/bin/git</code>.</p>
<pre><code class="language-php">...
    echo shell_exec(&quot;/full/path/to/bin/git pull 2&gt;&amp;1&quot;);
...
</code></pre>
<p>Now it was reporting the next issue...</p>
<h2 id="permissions">permissions</h2>
<pre><code>error: cannot open .git/FETCH_HEAD: Permission denied
</code></pre>
<p>The apache user also needs read and write access to the entire repository.</p>
<pre><code>chown -R ssh_user:www repository/
</code></pre>
<p>It's also a good idea to make sure any files/directories inherit this ownership if being created by others by setting the group sticky bit.</p>
<pre><code>chmod -R g+s repository/
</code></pre>
<h2 id="hostkeyverificationfailed">&quot;Host key verification failed&quot;</h2>
<p>Next, you need to do an intial git pull with the apache user to make sure the remote is added to the apache user's <code>known_hosts</code> file</p>
<pre><code>sudo -u www git pull
</code></pre>
<h2 id="sshkey">ssh key</h2>
<p>Another consideration created by this command being run by the apache user is the ssh key it uses to communicate with the remote repository.</p>
<p>First, I went down the path of attempting to use the <code>GIT_SSH</code> environment variable to set the <code>ssh -i</code> option to tell it to use a specific ssh key I had generated with the ssh user.  I never got this to work, most likely because there are a lot of rules ssh uses to determine the safety of a given key.  It requires some specific permissions regarding the user that is attempting to use the key.</p>
<p>An easier way I discovered was to give the apache user a home directory (via <code>/etc/passwd</code>) and a <code>.ssh</code> directory and then run the <code>ssh-keygen</code> command <strong>as</strong> the apache user (<code>www</code>)</p>
<pre><code>sudo -u www ssh-keygen -t rsa
</code></pre>
<p>This creates the keys and puts them in their expected location with the proper permissions applied.</p>
<p>Then I added the key as a read-only key for the BitBucket repository and everything worked as expected.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Problem using JSON to serialize PHP structures]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Yesterday I found an interesting quirk while working with a code base that uses <a href="http://php.net/manual/en/function.json-encode.php"><code>json_encode</code></a> and <a href="http://php.net/manual/en/function.json-decode.php"><code>json_decode</code></a> to serialize data moving in and out of the database.</p>
<p>The benifits of using JSON over standard PHP serialization (for basic objects) are fairly obvious:</p>
<ul>
<li>Data portability</li>
<li>Easier to parse by</li></ul>]]></description><link>http://3.89.81.88:80/problem-using-json-to-serialize-php-structures/</link><guid isPermaLink="false">5f5feb2b37e63f0d55cc5c4d</guid><dc:creator><![CDATA[Jonathan Johnson]]></dc:creator><pubDate>Fri, 28 Sep 2012 18:12:11 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Yesterday I found an interesting quirk while working with a code base that uses <a href="http://php.net/manual/en/function.json-encode.php"><code>json_encode</code></a> and <a href="http://php.net/manual/en/function.json-decode.php"><code>json_decode</code></a> to serialize data moving in and out of the database.</p>
<p>The benifits of using JSON over standard PHP serialization (for basic objects) are fairly obvious:</p>
<ul>
<li>Data portability</li>
<li>Easier to parse by hand (manual database updates)</li>
<li>Lighter weight in general</li>
</ul>
<p>But there is one gotcha...  Consider this example:</p>
<pre><code class="language-php">$php_struct = array(
    &quot;key&quot; =&gt; 5,
    &quot;another&quot; = &quot;data&quot;,
);

$json_string = json_encode( $php_struct );

//...

$php_struct = json_decode( $json_string );

// array? Nope, this is an object
echo gettype($php_struct);
</code></pre>
<h2 id="expectedunexpectedbehavior">Expected Unexpected Behavior</h2>
<p>The problem here is that most often when using a serialization method in/out of the database, it should be hidden and abstracted into the boilerplate database interaction.  The expectation is that if you put one thing in, you get the same thing out.  Which is not the case when feeding these json functions associative arrays.</p>
<h2 id="thearrayflag">The Array Flag</h2>
<p><code>json_decode()</code> does provide a second parameter to tell it you want objects decoded as associative arrays, but again, this simply flips the problem on it's head.  You encode an object and when it's decoded, you get an array back.  It is still possible to put one thing in, and get a different thing out.</p>
<h2 id="solution">Solution?</h2>
<p>The only solution I can think of is something like this...</p>
<h3 id="serialize">Serialize</h3>
<pre><code class="language-php">// $php_struct is our data

// Create a wrapper object
$obj = new stdClass;

// encode the actual data
$obj-&gt;data = json_encode( $php_struct );

// Store whether or not it is an array
$obj-&gt;is_array = is_array( $php_struct );

// encode for storage
$obj_json = json_encode( $obj );
save( $obj_json );
</code></pre>
<h3 id="deserialize">De-serialize</h3>
<pre><code class="language-php">$obj_json = retrieve();
$obj = json_decode( $obj_json );
$php_struct = json_decode( $obj-&gt;data, $obj-&gt;is_array );
</code></pre>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>