<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><description>Imagine Easy is an educational technology and media company. We envision a world where education is at the core of our living and working environments. Learn more about us at http://www.imagineeasy.com

Let us know if you’re interested in joining our team via devjobs@imagineeasy.com</description><title>imagine easy / dev</title><generator>Tumblr (3.0; @drafts)</generator><link>https://dev.imagineeasy.com/</link><item><title>Testing Logging in Silex</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://silex.sensiolabs.org/" target="_blank"&gt;Silex&lt;/a&gt; is a PHP microframework from the same family as &lt;a href="http://symfony.com/" target="_blank"&gt;Symfony&lt;/a&gt;. My shop, &lt;a href="http://www.imagineeasy.com/" target="_blank"&gt;Imagine Easy Solutions&lt;/a&gt;, uses Silex for some of our most important applications.&lt;/p&gt;

&lt;p&gt;Modular setup is at the core of Silex&amp;rsquo;s game, by means of Service Providers. The &lt;a href="http://silex.sensiolabs.org/doc/providers/monolog.html" target="_blank"&gt;MonologServiceProvider&lt;/a&gt; makes it easy to add highly configurable logging to your application.&lt;/p&gt;

&lt;p&gt;But how to test your logging? It turns out that this Service Provider includes a &lt;code&gt;DebugHandler&lt;/code&gt; which you can use to make log entries available in array form.&lt;/p&gt;

&lt;p&gt;The complete sample app for this post is available at &lt;a href="https://github.com/yitznewton/silex-log-test" target="_blank"&gt;https://github.com/yitznewton/silex-log-test&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the purposes of this post, we&amp;rsquo;ll assume you&amp;rsquo;ve already set up logging &amp;ndash; you can compare your &lt;code&gt;composer.json&lt;/code&gt; and bootstrap with the ones in the sample repo. The question is, how to access the logs from your tests.&lt;/p&gt;

&lt;p&gt;In the test setup, we need to inject a &lt;code&gt;DebugHandler&lt;/code&gt; into our Silex container.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;namespace Yitznewton\SilexLogTest\Tests;

use Monolog\Logger;
use Silex\WebTestCase;
use Symfony\Bridge\Monolog\Handler\DebugHandler;
use Symfony\Component\HttpKernel\HttpKernel;

class WebTest extends WebTestCase
{
    /** @var DebugHandler */
    private $logHandler;

    public function setUp()
    {
        parent::setUp();
        $this-&amp;gt;logHandler = new DebugHandler();
        $this-&amp;gt;app['logger'] = new Logger('test', [$this-&amp;gt;logHandler]);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As an alternative, we can use the &lt;code&gt;DebugHandler&lt;/code&gt; that comes pre-wired in the &lt;code&gt;MonologServiceProvider&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function setUp()
{
    parent::setUp();
    $this-&amp;gt;logHandler = $this-&amp;gt;app['monolog.handler.debug'];
    $this-&amp;gt;app['monolog']-&amp;gt;pushHandler($this-&amp;gt;logHandler);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, we need to examine the collected logs so we have something to assert against:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;private function assertLogEntry($level, $message)
{
    $logMatches = function ($record) use ($level, $message) {
        if ($record['level'] != $level) {
            return false;
        }

        return strpos($record['message'], $message) !== false;
    };

    $records = array_filter($this-&amp;gt;logHandler-&amp;gt;getRecords(), $logMatches);
    $this-&amp;gt;assertNotEmpty($records, 'Failed asserting that a log entry was made.');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now can test the presence of a log entry with a given log level, matching a given message.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/**
 * @test
 */
public function notOk()
{
    $client = $this-&amp;gt;createClient();
    $client-&amp;gt;request('GET', '/do-something/not-ok');
    $this-&amp;gt;assertLogEntry(Logger::ERROR, 'woe is me!');
}
&lt;/code&gt;&lt;/pre&gt;</description><link>https://dev.imagineeasy.com/post/102394035784</link><guid>https://dev.imagineeasy.com/post/102394035784</guid><pubDate>Tue, 11 Nov 2014 17:03:21 -0500</pubDate><category>silex</category><category>php</category><category>testing</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Decoupling Domain Modules in AngularJS</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The story and examples in this post are taken from my experience with Angular,
but from my cursory survey of popular JavaScript frameworks, the ideas
apply just as much to Ember.js and others.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;m an avowed Uncle Bob-ist when it comes to&amp;hellip; well, most things. In this
context, I have embraced his
&lt;a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html" target="_blank"&gt;Clean Architecture&lt;/a&gt;,
which describes why and how to
define and enforce boundaries between large-scale areas of responsibility within
an application, such as&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;business logic&lt;/li&gt;
&lt;li&gt;frameworks (integration with HTTP, etc.)&lt;/li&gt;
&lt;li&gt;object storage (database abstraction layers, etc.)&lt;/li&gt;
&lt;/ul&gt;&lt;iframe src="//player.vimeo.com/video/43612849" width="500" height="281" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;a href="http://vimeo.com/43612849" target="_blank"&gt;Robert C. Martin - Clean Architecture&lt;/a&gt; from &lt;a href="http://vimeo.com/ndcoslo" target="_blank"&gt;NDC Conferences&lt;/a&gt; on &lt;a href="https://vimeo.com" target="_blank"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Wrecked Angular&lt;/h2&gt;

&lt;p&gt;This predilection led to an acute point of discomfort for me when my team
began working on a new project in AngularJS. This Model-View-Whatever
JavaScript framework offers its own dependency injection facility, and in the code
examples that I&amp;rsquo;ve seen, &lt;strong&gt;this DI service is injected into domain modules&lt;/strong&gt;, so that they can in turn access their own dependencies.&lt;/p&gt;

&lt;p&gt;This is the controversial &lt;strong&gt;Service Locator&lt;/strong&gt; pattern, and here, it has an unfortunate
result that erodes the Clean Architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In allowing a business domain module to request its own dependencies via
Angular&amp;rsquo;s DI service, you are giving knowledge about the framework to the
domain, and forever coupling them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The domain code should be the most core part of the application; in theory, it
could exist as part of a Node.js application on a server, or a hypothetical
Android.js application where Angular would not be used. By introducing Angular
into your code, you are preventing yourself from ever using it outside of an
Angular application. Such a coupling would also make it impossible to reuse
your domain code in e.g. Ember.js, in case Angular should die, or Ember introduce
some killer feature that you want to leverage.&lt;/p&gt;

&lt;p&gt;Another outcome of having the framework baked into your domain is that you need
to load the framework in order to run your tests, which can be complicated and
can also erode performance. In a domain with relatively simple POJOs and few
dependencies, you should be able to run your tests fast and without fanfare.&lt;/p&gt;

&lt;p&gt;So how do we break this coupling and allow our domain code to stand on its own
two feet?&lt;/p&gt;

&lt;p&gt;The simple answer is to make sure that all the module&amp;rsquo;s dependencies are
injected explicitly, typically as constructor parameters; however, I was unable
to find any examples of this mode of decoupled design on the webz.&lt;/p&gt;

&lt;h2&gt;How to do it&lt;/h2&gt;

&lt;p&gt;With some JavaScript help from my colleague Cameron, I was able to pull together
a solution over the course of a couple days of intermittent experimentation.
Notice how the domain code (the &amp;ldquo;trelloboard/repository&amp;rdquo; module) has no knowledge of
Angular.&lt;/p&gt;

&lt;p&gt;Our example application is a &lt;a href="http://trello.com" target="_blank"&gt;Trello&lt;/a&gt; clone. I&amp;rsquo;ve
implemented a bare-bones repository object which returns &lt;code&gt;Trelloboard&lt;/code&gt;
entities. Presumably it would look them up by ID, but in this naive
implementation, we&amp;rsquo;re just hardcoding it.&lt;/p&gt;

&lt;p&gt;Each &lt;code&gt;Trelloboard&lt;/code&gt; has a number of &lt;code&gt;CardGroups&lt;/code&gt;. We&amp;rsquo;re using RequireJS for
loading.&lt;/p&gt;

&lt;p&gt;The test injects the &lt;code&gt;q&lt;/code&gt; dependency directly into the module, and the Angular
&lt;code&gt;services&lt;/code&gt; module wires our module into the framework before the controller
needs it.&lt;/p&gt;

&lt;h3&gt;The module&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;// trelloboard/repository.js
define(function() {
  'use strict';

  function TrelloboardRepository($q) {
    this.$q = $q;
  }

  TrelloboardRepository.prototype = {
    find: function() {
      // first iteration: just return a hard-coded Trelloboard
      var output = this.$q.defer();

      output.resolve({
        cardGroups: [
          {
            name: 'Ungrouped',
            cards: []
          }
        ]
      });

      return output.promise;
    }
  };

  return TrelloboardRepository;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;The spec&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;define(['trelloboard/repository', 'q'], function(TrelloboardRepository, q) {
  'use strict';

  var trelloboardRepository;

  describe('TrelloboardRepository', function() {
    beforeEach(function() {
      trelloboardRepository = new TrelloboardRepository(q);
    });

    describe('#find', function() {
      it('returns a Trello board', function() {
        trelloboardRepository.find(1).then(function(trelloboard) {
          trelloboard.cardGroups.should.be.instanceof(Array);
        });
      });
    });
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;The AngularJS service loader (not used when unit-testing)&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;// trelloboard/services.js
define([
  'app', // the AngularJS kernel
  'trelloboard/repository'
], function(
  app,
  TrelloboardRepository
) {
  'use strict';

  app.service('TrelloboardRepository', TrelloboardRepository);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Our controller&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;define(['app', 'trelloboard/services'], function(app) {
  'use strict';

  // TrelloboardRepository is magically injected by Angular, now that we've
  // wired it up in trelloboard_services
  app.controller('TrelloboardIndexController', function($scope, TrelloboardRepository, $stateParams) {
    TrelloboardRepository.find($stateParams.id).then(function(trelloboard) {
      $scope.model = trelloboard;
    });
  });
});
&lt;/code&gt;&lt;/pre&gt;</description><link>https://dev.imagineeasy.com/post/100670193679</link><guid>https://dev.imagineeasy.com/post/100670193679</guid><pubDate>Wed, 22 Oct 2014 11:07:00 -0400</pubDate><category>clean code</category><category>Architecture</category><category>code design</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Don't abuse the closures</title><description>&lt;p&gt;by Pream Totaram&lt;/p&gt;

&lt;h1&gt;I started to read about clean coding practices and started to wonder how they can apply to JavaScript where it is common to define a function within a function. What I started to think is, how could it be possible for a block of code to obey the Single Responsibility Principle and stay mobile, when you have a function within a function. Time to investigate. Coming from my background, languages with classes (like PHP and Java), it took me a while to realize that a function in JavaScript is a more general concept than I’m used to. But I do realize it’s a ability that does get abused. First, what is the Single Responsibility Principle?&lt;/h1&gt;

&lt;p&gt;It states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;div&gt;A class should have only one reason to change&lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every object (since we are in JavaScript and everything is an object here) should obtain one, and only one goal. Functions, which are also objects, can nest functions, which took me a while to really understand at first, but I’ve come to appreciate how powerful this really is.&lt;/p&gt;

&lt;blockquote&gt;
&lt;div&gt;With great power, comes great responsibility&lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;– Stan Lee&lt;/p&gt;

&lt;p&gt;Although, I immediately saw the risk in allowing this. When I understand that in JavaScript, functions can be used very well to limit scope, it is still possible to use it in such a way without breaking SRP and keeping your code mobile.&lt;/p&gt;

&lt;h2&gt;Good&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;
define([
  'jquery',
  'underscore',
  'hyperagent'
], function($,_,hyperagent){
  var doSomething = function(){
    //do something here that would return get a HAL object using $.ajax
    //return the object
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This instance shows an instance where you are loading modules from RequireJS. the parent function is being used primarily to limit scope, to avoid working in the global scope. Working in the global scope in JavaScript can be dangerous, due to possible code collision from anything that may load on the page. However, if you need to reuse any of the child functions, it would be pretty easy. In this case, you would just have to worry about third party packages (jquery, underscore, hyperagent), that you may possibly be using in the destination code. This is also an instance of objeying the SRP, because the parent function only has one job, that is to limit scope (which includes providing access to libraries you may want to use in the scope).&lt;/p&gt;

&lt;h2&gt;Bad&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;
function doALargeTask()
{
    var that = this;
    var smallerTask = function () {
        //code that heavily uses that
    }

    smallerTask();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this case, it could be extremely helpful in a later situation to use smallerTask(), but as the method grows and grows, it would be increasingly tough to reuse it, because it would potentially rely more and more on the parent method. However, if you pull the child method out early, and only pass to it what you need, you can certain that both doALargeTask() and smallerTask() only do one thing.&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/98240997084</link><guid>https://dev.imagineeasy.com/post/98240997084</guid><pubDate>Tue, 23 Sep 2014 14:21:00 -0400</pubDate><category>javascript</category><dc:creator>easybibpream</dc:creator></item><item><title>Naming things considered hard</title><description>&lt;p&gt;by &lt;a href="https://twitter.com/dazzlog" target="_blank"&gt;Anne-Julia Scheuermann (@dazzlog)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week I gave a talk at the Berlin PHP Usergroup about naming things.&lt;/p&gt;

&lt;p&gt;For us developers it is a constant task to find the right words for describing things and giving them a context to create meaning and transporting what that thing is about to do to other developers.&lt;/p&gt;

&lt;p&gt;In my slidedeck I put together a small guideline to share what I found:&lt;/p&gt;

&lt;p&gt;[&lt;/p&gt;

&lt;figure class="tmblr-full" data-orig-height="791" data-orig-width="1024" data-orig-src="https://speakerd.s3.amazonaws.com/presentations/80400fa0157901328ad97a292d371260/slide_0.jpg?1409736202"&gt;&lt;img src="https://66.media.tumblr.com/d57b5eb076e2d69c23232793ab698864/tumblr_inline_p7gurwfDDw1rt3oue_540.jpg" data-orig-height="791" data-orig-width="1024" data-orig-src="https://speakerd.s3.amazonaws.com/presentations/80400fa0157901328ad97a292d371260/slide_0.jpg?1409736202"/&gt;&lt;/figure&gt;&lt;p&gt;](&lt;a href="https://speakerdeck.com/dazz/nomen-est-omen-naming-things-considered-hard" target="_blank"&gt;https://speakerdeck.com/dazz/nomen-est-omen-naming-things-considered-hard&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&amp;ndash; Anne&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/96604754704</link><guid>https://dev.imagineeasy.com/post/96604754704</guid><pubDate>Thu, 04 Sep 2014 03:20:58 -0400</pubDate><category>php</category><category>naming</category><category>design</category><category>talk</category><category>slides</category><dc:creator>hakindazs</dc:creator></item><item><title>Bootstrapping a New Project: XP Epiphany</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our team has recently begun working on a new product, and dedicated eight developers for the task. We have been struggling with how to get the product from concept into implementation. We&amp;rsquo;re using an up-front planning approach, specifying detailed understanding of both structure of the system (code architecture and design) and the way we&amp;rsquo;ll be constructing it. The planning is done at the beginning of a sprint, and we even did some initial work that was meant to span sprints.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ve discovered that making decisions and building consensus this way is messy, time-consuming and emotionally tiresome, especially when we have nothing on the ground to work off of. We&amp;rsquo;re also spending a lot of time trying to predict and pre-design the parts of the system and how they will fit together, introducing many utilities up front and imposing/arguing about a file structure to support those many expected parts.&lt;/p&gt;

&lt;p&gt;On the train this morning, I was reading
&lt;a href="http://www.amazon.com/Extreme-Programming-Explained-Embrace-Edition/dp/0321278658" target="_blank"&gt;Extreme Programming Explained&lt;/a&gt; and discovered these magic words from Kent Beck in chapter 10:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The architecture for a little system should not be the same as for a big system. [&amp;hellip;] First a small team writes a small system. Then they find the natural fracture lines and divide the system into relatively independent parts for expansion. The architects help choose the most appropriate fracture lines and the follow the system as a whole, keeping the big picture in mind as the groups focus on their smaller section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So you begin with a single pair sitting with the product owner to create a minimal implementation of one or a handful of stories. Consensus is easy, and design fits the needs of the system at this scale. As you continue building out, adding a server, supporting libraries, etc., the boundaries between layers emerge, allowing you to scale your team out, and split work along those boundaries. Communication about localized design concerns is contained within the smaller layer sub-teams; communication across teams is dedicated to specifying and refining the boundary interfaces that define the services one layer provides to another.&lt;/p&gt;

&lt;p&gt;One big upside to experiencing our bigger-process deadlock was the high level of communication and patience it demanded from everyone on the team. It forced us to look hard for the most optimal process for the configuration of our team.&lt;/p&gt;

&lt;p&gt;Takeaways for the future: where possible, limited the number of developers initially working on the product, and scale out the team together with the project to avoid the difficulty of mob decision-making.&lt;/p&gt;

&lt;p&gt;This is just the beginning of a great product, and if you&amp;rsquo;re interested in joining our ever-evolving team, reach out at &lt;a href="mailto:devjobs@imagineeasy.com" target="_blank"&gt;devjobs@imagineeasy.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Yitz is NYC Technical Lead for Imagine Easy Solutions&lt;/em&gt;&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/93308127529</link><guid>https://dev.imagineeasy.com/post/93308127529</guid><pubDate>Wed, 30 Jul 2014 09:59:00 -0400</pubDate><category>extreme programming</category><category>software design</category><category>software architecture</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Intro to PHP extensions</title><description>&lt;p&gt;These are the slides for a talk about writing PHP extensions that I gave at the &lt;a href="http://www.bephpug.de/2014/07/01/july.html" target="_blank"&gt;Berlin PHP User Group&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.google.com/presentation/d/1A4lWM2EKjGghi3jV2nF8ZWmw0Ew8YNPlEh6_uWdPoyw/pub?start=false&amp;amp;loop=false&amp;amp;delayms=3000" target="_blank"&gt;Extending PHP - How to mount a rocket launcher on the back of an elephant (online)&lt;/a&gt; (&lt;a href="http://r-wos.org/media/phpext.pdf" target="_blank"&gt;PDF version&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;The code I used for demos is &lt;a href="https://github.com/rwos/hello-world-php-ext" target="_blank"&gt;available on github &lt;/a&gt;and can serve as a kind of starting point for PHP extensions.&lt;/p&gt;
&lt;p&gt;Other than that, the main thing to know is to not bother with the official documentation on php.net - it&amp;rsquo;s incomplete and outdated in parts - and to go straight to blog posts and other &lt;a href="http://devzone.zend.com/303/extension-writing-part-i-introduction-to-php-and-zend/" target="_blank"&gt;resources on the net&lt;/a&gt;. Google is your friend here.&lt;/p&gt;
&lt;p&gt;Another good resource are the &lt;a href="https://github.com/php/php-src/tree/master/ext" target="_blank"&gt;extensions that ship with php&lt;/a&gt;. They are of varying quality but most can serve as decent examples for how to get your own extension off the ground.&lt;/p&gt;
&lt;p&gt;Happy Hacking!&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&amp;ndash; &lt;a href="http://r-wos.org/" target="_blank"&gt;Richard Wossal&lt;/a&gt;&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/91465859054</link><guid>https://dev.imagineeasy.com/post/91465859054</guid><pubDate>Fri, 11 Jul 2014 13:01:52 -0400</pubDate><category>php</category><category>c</category><category>talk</category><dc:creator>badlynamedcode</dc:creator></item><item><title>The Realtime Web with Socket.IO and RabbitMQ</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have been thinking a lot about the best way to implement a realtime collaborative web app. WebSockets is the maturing tech of choice for this, and although there still seem to be some issues in terms of support, things are improving. Internet Explorer has support as of version 10. Mobile carriers and some institutional firewalls might implement some network-level impediments, but &lt;a href="http://blog.hekkers.net/2012/12/09/websockets-and-mobile-network-operators/" target="_blank"&gt;apparently it&amp;rsquo;s possible to serve WebSockets over port 443 and largely escape this problem&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;WebSockets inherently offers a two-way connection between a single browser session and the server; the broader context of what other clients might be connected to the application (such as in a collaborative setting) is outside of the scope of WebSockets. There are several solutions already out there for broadcasting across sessions; the most interesting to my mind are
&lt;a href="http://socket.io/" target="_blank"&gt;Socket.IO&lt;/a&gt; (node.js),
&lt;a href="http://faye.jcoglan.com" target="_blank"&gt;Faye&lt;/a&gt; (node.js and Ruby),
and &lt;a href="http://autobahn.ws" target="_blank"&gt;Autobahn&lt;/a&gt;  (node.js, Python and more).
I decided to use Socket.IO to begin my investigation, based on&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;the high visibility of Socket.IO as per Google Trends,&lt;/li&gt;
&lt;li&gt;a &lt;a href="http://blog.fogcreek.com/the-trello-tech-stack/" target="_blank"&gt;high-profile adoption by the Trello team&lt;/a&gt;, as well as&lt;/li&gt;
&lt;li&gt;their fairly well-documented falling-out&lt;/li&gt;
&lt;li&gt;and my personal preference at first glance for its API.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This is my first experience working with node.js, so&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;don&amp;rsquo;t assume I know what I&amp;rsquo;m doing, and copy-n-paste my code&lt;/li&gt;
&lt;li&gt;go easy :}&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Scalability&lt;/h2&gt;

&lt;p&gt;As I was proceeding with research, the one class of thing that kept popping up in blogs, etc. was scalability issues. I was not really interested in solving those problems within Socket.IO or figuring out if it is still an issue with the current release; for now I&amp;rsquo;m just maintaining &lt;a href="https://pinboard.in/u:yitznewton/t:socketio/t:scalability" target="_blank"&gt;a list of articles about the topic&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Instead, I looked for a way to incorporate Socket.IO into our stack without putting any scaling pressure on it directly.&lt;/p&gt;

&lt;h2&gt;Solution: use Socket.IO as a dumb transport&lt;/h2&gt;

&lt;p&gt;My experimental solution is to maintain a cluster of Socket.IO processes whose only function is to maintain the browser connections, and shuttle messages to and from a message queue. With this arrangement, each Socket.IO process is independent of the others, so there is no shared backend or storage to scale. These messages constitute both incoming job requests (e.g. &amp;ldquo;hey server, update a particular entity&amp;rdquo;), and outgoing announcements (&amp;ldquo;hey everyone, entity 123 has been updated&amp;rdquo;). I chose &lt;a href="http://www.rabbitmq.com/" target="_blank"&gt;RabbitMQ&lt;/a&gt; as the messaging server for this experiment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caveat:&lt;/strong&gt; I have not yet devised a testing plan to compare this architecture with a &amp;ldquo;plain&amp;rdquo; Socket.IO setup, so I can&amp;rsquo;t say whether this actually makes anything better, only that it avoids any poor design that might have hampered multi-process Socket.IO installations.&lt;/p&gt;

&lt;h2&gt;Bonus: forced decoupling of application code&lt;/h2&gt;

&lt;p&gt;An extremely useful bonus involved the application code, as distinct from the transport layer. This insight might even be worth more to me than any Socket.IO-specific benefits.&lt;/p&gt;

&lt;p&gt;I had been concerned, with these node.js-based server scenarios, about the idea of implementing an application server in JavaScript. Our team&amp;rsquo;s server-side specialists (including me) don&amp;rsquo;t have deep experience with node or JS in general, and with my bias toward type safety features, I personally have misgivings about writing complex things in JavaScript, as opposed to our usual mode of somewhat-type-safe PHP. (I discovered that &lt;a href="http://twitter.com/vanbosse" target="_blank"&gt;@vanbosse&lt;/a&gt; utilized this same concept in
&lt;a href="http://vanbosse.be/blog/detail/pub-sub-with-rabbitmq-and-websocket" target="_blank"&gt;his post dealing with a very similar application of RabbitMQ&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;When we treat all requests and responses as generic, context-agnostic messages, and let the &lt;em&gt;application core&lt;/em&gt; pull them off a queue and &amp;ldquo;report back&amp;rdquo; in this generic way (as opposed to specialized ones like &lt;code&gt;HttpRequest&lt;/code&gt;/&lt;code&gt;HttpResponse&lt;/code&gt;), we force ourselves to decouple the application code quite starkly from the transport layer.&lt;/p&gt;

&lt;p&gt;In most &amp;ldquo;MVC framework&amp;rdquo; situations like working with Rails or Symfony, the best you can hope for is to consciously keep your code decoupled from the web framework you&amp;rsquo;re using, and that takes discipline. Here, however, our point of departure is a &amp;ldquo;message-in, message-out&amp;rdquo; application &amp;ndash; pretty much perfectly echoing the Uncle Bobbian
&lt;a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html" target="_blank"&gt;Clean Architecture&lt;/a&gt;.
(See also &lt;a href="https://www.destroyallsoftware.com/talks/boundaries" target="_blank"&gt;Gary Bernhardt&amp;rsquo;s talk&lt;/a&gt;
on boundaries for more architecture porn.)
Not only have we made ourselves implement an ideal interface for testability, we have also freed ourselves to make open decisions about the messaging stack, and even change our minds later. Socket.IO not working out? Just swap in Faye, and all you need to do is write a new messaging adapter for the Faye-RabbitMQ interface. The application itself is unchanged.&lt;/p&gt;

&lt;h2&gt;Proof of concept: SockBit&lt;/h2&gt;

&lt;p&gt;To demonstrate this approach, I have created a
&lt;a href="https://github.com/yitznewton/sockbit" target="_blank"&gt;prototype note-editing application, SockBit&lt;/a&gt;.
In function, it is sort of like an unfinished 5% of Trello. It uses this stack to allow users to edit notes collaboratively in realtime; when one user edits a note and blurs the input, the change is sent to the server, where it is persisted, and then pushed up to other clients. Here&amp;rsquo;s a screencast of me demonstrating it.&lt;/p&gt;

&lt;iframe width="640" height="440" src="//www.youtube.com/embed/Z8BHrZUPKI0" frameborder="0" allowfullscreen style="margin-bottom: 30px"&gt;&lt;/iframe&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This was a really fun exercise, and has served as a great demonstration of the possibilities of Clean Architecture in action. The next step will be to see if I can test the scalability of this architecture in comparison with a straight Socket.IO version. My next stop will be checking out &lt;a href="http://sorcery.smugmug.com/2013/12/17/using-phantomjs-at-scale/" target="_blank"&gt;PhantomJS at scale&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Yitz is NYC Technical Lead for Imagine Easy Solutions&lt;/em&gt;&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/91224992649</link><guid>https://dev.imagineeasy.com/post/91224992649</guid><pubDate>Wed, 09 Jul 2014 01:10:00 -0400</pubDate><category>websocket</category><category>architecture</category><category>socket.io</category><category>rabbitmq</category><category>node.js</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Choosing your Automated Acceptance Testing framework</title><description>&lt;div class="author-photo"&gt;&lt;figure data-orig-height="132" data-orig-width="144" data-orig-src="https://66.media.tumblr.com/956c7dcc405ebdc4e7d0d7a5b2492d16/tumblr_inline_n81q6ckpqm1sjppuq.png"&gt;&lt;img alt="image" src="https://66.media.tumblr.com/956c7dcc405ebdc4e7d0d7a5b2492d16/tumblr_inline_p7gurvLErF1sjppuq_540.png" data-orig-height="132" data-orig-width="144" data-orig-src="https://66.media.tumblr.com/956c7dcc405ebdc4e7d0d7a5b2492d16/tumblr_inline_n81q6ckpqm1sjppuq.png"/&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;My name is Asia Wolf, and I’m Imagine Easy’s first QA hire. I’ve been writing automated acceptance tests and performing manual regression tests since April 15th, 2014. &lt;/p&gt;
&lt;p&gt;After I studied computer science at Carnegie Mellon University, I got my first job as a Quality Assurance Engineer. This was supposed to be the first step on my way to become a “real” web developer. My task was to automate testing for a e-commerce startup. Knowing nothing about automated acceptance testing, I searched the internet for the right framework to use. Unfortunately, most of the articles I could find were incredibly outdated and only talked about one framework’s good or bad points. Since then, I’ve built 3 automated acceptance testing suites in &lt;strong&gt;CasperJS, Selenium with RubyBindings and Appium, &lt;/strong&gt;and&lt;strong&gt; Selenium with JavaBindings&lt;/strong&gt; as well as doing regular research on the tools on the market such as &lt;strong&gt;Cucumber, Behat, &lt;/strong&gt;and&lt;strong&gt; Watir.&lt;/strong&gt; There are almost endless combinations of frameworks you can use for testing, so I hope that by comparing frameworks and advising based on my experience I can help spare your QA team some frustration in choosing the right framework.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This is mostly geared towards small automation teams who do not need to support Windows or various versions of Internet Explorer (which should probably be manually tested anyway). For those of you who have to support Windows and IE, this is not going to be terribly informative. You should check out Telerik Test Studio, UFT (detailed below), or Selenium Webdriver 2 with IE bindings.&lt;/p&gt;
&lt;h2&gt;&lt;a href="http://docs.seleniumhq.org/docs/03_webdriver.jsp" title="Selenium Webdriver 2" target="_blank"&gt;Selenium Webdriver 2&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The good:&lt;/strong&gt; You can automate most browsers and mobile devices in many different programming languages. It’s pretty widely adopted across other frameworks as well, and can integrate with BDD tools such as Cucumber. There are meetups and conferences and Google Hangouts where you can find support. Selenium is pretty easy to pick up with some programming knowledge. I’ve used Selenium with Java with only minor frustration, and Selenium with Ruby and Rspec combined well with minimal set-up for an easy-to-read output and code. You can also use Selenium Grid/Server or SauceLabs to run your tests in parallel across multiple machines.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The bad:&lt;/strong&gt; Just because you can do almost anything doesn’t mean you should. It’s very tempting to try to make your test suite run on every browser and support mobile devices, but the maintenance cost is very high and it’ll take you a while to figure out how to make each browser’s driver work with your code. I found that utilizing Selenium’s capabilities to run across browsers and devices and in parallel on Sauce was a lot of effort for very little reward. I can remember only one instance where the other browsers caught a bug, because many cross-browser bugs are visual and won’t be caught by automation. All of that effort you spend maintaining can’t be spent making new tests, and you still have to manually check those browsers for visual bugs.&lt;/p&gt;
&lt;p&gt;Selenium Webdriver’s documentation leaves something to be desired. I want easy-to-find API docs with good explanations of all of the things I can do, linked from a Getting Started page; but that is not something I can find with Selenium. There are docs, but you have to dig to get to them.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://seleniumhq.wordpress.com/2013/08/28/the-road-to-selenium-3/" target="_blank"&gt;Selenium 3&lt;/a&gt; was promised in August 2013 for a December 2013 release and has been delayed approximately 6 months so far. An effort to combine it with a W3C spec is causing the lateness. After a quick look at the documentation they’ve released so far, I’m not terribly excited and don’t see myself using it for future automation projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You should use this if:&lt;/strong&gt; There are a few cases for choosing Selenium. Maybe your QA team doesn’t have a lot of programming experience and wants to use the language they’re most comfortable with. It’s easy to get support, and you don’t have to learn a new language’s syntax. This approach is also good if you’re a developer making Selenium tests for your product - you can write in the same language your product is in without having to switch contexts as much. Just don’t overreach and try to make it run in every browser on Sauce Labs.&lt;/p&gt;
&lt;p&gt;I would mainly recommend Selenium for large teams who intend to utilize the cross-platform and cross-browser testing features or use Sauce Labs. The maintenance cost will be high, but if you have the patience and bandwidth, go for it. Selenium is a widely-adopted and powerful tool for automation and can help you achieve your wildest automated testing dreams if you’re dedicated enough.&lt;/p&gt;
&lt;h2&gt;&lt;a href="http://casperjs.org" target="_blank"&gt;CasperJS&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The good:&lt;/strong&gt; I have to start this section out by admitting some bias. I’ve used CasperJS, Selenium, and Cucumber previously and CasperJS is by far my favorite to work with. Writing CasperJS scripts is just more fun. I learned Javascript entirely because I wanted to use this framework, and I am so glad I did. It’s really convinced me that headless is the way to go for automated testing.&lt;/p&gt;
&lt;p&gt;I’ve seen people complain about CasperJS’s &lt;a href="http://casperjs.readthedocs.org/en/latest/modules/casper.html" target="_blank"&gt;API&lt;/a&gt;, but I’ve found it incredibly helpful compared to the digging I had to do with Selenium. The tester module makes your passes and fails very clear, and the tester &lt;a href="http://casperjs.readthedocs.org/en/latest/modules/tester.html" target="_blank"&gt;API&lt;/a&gt; is also nice to work with. You can write your tests in CoffeeScript or JavaScript, and if you can’t figure out how to do what you want in CasperJS you can do it in JavaScript or CoffeeScript. CasperJS is quick, light-weight, and easy to set up. There are very helpful getting started guides for beginners, and one of our interns went from zero programming experience to writing tests in CasperJS in less than two weeks.&lt;/p&gt;
&lt;p&gt;Going headless for your automated tests is, in my opinion, the best choice. Automated tests will most likely not completely replace manual testing, and headless browsing takes less time and minimizes the maintenance burden, because you’re not trying to figure out why your tests don’t work a certain way in one browser. This will leave you time for the inevitable manual testing, or for writing even more CasperJS scripts. For those of you who want to try CasperJS but would rather ease into it from Selenium’s easy-to-see Webdriver, I’d recommend running your scripts on &lt;a href="http://slimerjs.org" target="_blank"&gt;SlimerJS&lt;/a&gt;. Whereas PhantomJS uses Webkit, SlimerJS runs on Gecko, and launches a small browser window so you can follow along. SlimerJS is not quite ready for prime-time yet, and through experience I would not recommend using it for large test suites. I look forward to following the progress of SlimerJS in the future.&lt;/p&gt;
&lt;p&gt;While CasperJS doesn’t have quite as wide an adoption as Selenium, there are already a lot of great open-source tools to help you do a lot of cool things with it. There has been work to incorporate CasperJS with Mocha, Grunt, and Gulp. We use CasperJS with &lt;a href="https://travis-ci.org/" target="_blank"&gt;Travis&lt;/a&gt;, our continuous integration tool.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The bad: &lt;/strong&gt;Again, I’m pretty biased. Because my experience with CasperJS has been so positive, I have a hard time finding bad things to say about it. It’s a bit harder to get answers to your questions on the framework because of its newness, and the version I use is a developer version and thus has some bugs. A lot of the tools that work with CasperJS are very new and still have bugs to work out, so you may invest a good chunk of time into them before realizing that they are not mature enough to use for your testing. &lt;/p&gt;
&lt;p&gt;Headless browsing is sometimes intimidating; debugging is not incredibly fun to do when you can’t see what your code is doing in a browser. CasperJS’s debug mode combined with its methods to capture screenshots are a good substitute in my opinion, but be patient when you start learning this framework. You can use SlimerJS to see part of the page you’re on for easier debugging, but the engines run a bit differently and what passes on SlimerJS may not always pass on CasperJS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You should use this if:&lt;/strong&gt; CasperJS is a great tool for small teams. The output of test passes and fails gets kind of unmanageable once you have a lot of test files, so you may want to look into writing something that outputs a digest of test results to avoid minutes of scrolling. Use this if you’re a small team who wants to make tests quickly. Use this if you know and love Javascript or Coffeescript and want to write your tests in one of those languages. Use this if you want to learn basic Javascript or Coffeescript.&lt;/p&gt;
&lt;h2&gt;&lt;a href="http://cukes.info/" target="_blank"&gt;Cucumber/BDD tools in general&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;The good:&lt;/strong&gt; Cucumber, Behat, and other BDD tools (including Yadda which plugs into Casper but does not seem quite stable enough for use running tests yet) will restrict the format to combine your acceptance criteria with your automated acceptance tests. It forces you to think through your requirements and makes it easy for non-developers to read your code and run your tests. The syntax is easy to read for people who don’t code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The bad:&lt;/strong&gt; Here I have to admit more bias. Every time I start writing a new automation framework I test the part of an app in various languages to compare speed, flexibility, ease of writing tests, and general enjoyment of the language. I’ve never enjoyed writing Cucumber, and find the format kind of limiting. Thus, I have never continued past the experimental stage and actually maintained a cucumber suite.&lt;/p&gt;
&lt;p&gt;Many people see poorly developed acceptance criteria and leap to using a BDD tool right away. That might fix the problem, but it will complicate your automated acceptance testing stack unnecessarily. If the root cause is bad acceptance criteria, educate the person writing your acceptance criteria on how you’d like it written, and don’t start writing code until that criteria is clear. Additionally, people see poorly structured automated acceptance tests and leap to BDD. This is again fixing a problem by adding complexity and restrictions, rather than educating your engineers on good practices.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;You should use this if:&lt;/strong&gt; Now, my bias against BDD tools doesn’t completely prevent me from seeing the use. I’ve been a product manager and QA at the same time for the same product, and probably should have used Cucumber instead of Selenium. If your product managers or non-developers read and run your tests, this is probably a good choice. If you are a technical person and everyone reading and running your code is as well, you probably don’t need it. And if you don’t need it, don’t use it and complicate your stack.&lt;/p&gt;
&lt;h2&gt;Other frameworks and tools I did not include here&lt;/h2&gt;
&lt;p&gt;I obviously haven’t evaluated every tool on the market. I try not to spout opinions on things I am not informed on, so I can’t pass judgment or advice on the following tools that seem to be decently popular.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://watir.com/" target="_blank"&gt;Watir&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt;:&lt;/strong&gt; A ruby tool that never really set itself apart enough from Selenium for me to invest the time into investigating it. However, &lt;a href="http://watirmelon.com/" target="_blank"&gt;this blog&lt;/a&gt; by Allister Scott says some nice things about Watir and makes me wonder if I made the wrong choice, especially given my waning enthusiasm for Selenium. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www8.hp.com/us/en/software-solutions/unified-functional-testing-automation/index.html" target="_blank"&gt;HP Unified Functional Testing/QuickTest Professional&lt;/a&gt;:&lt;/strong&gt; I run anything but Windows if I have a choice, I like open-source projects, I don’t want to pay for a testing framework, and I have never met anyone who expressed any enthusiasm for this tool. But it does exist and is used pretty frequently at larger companies.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Look at the disclaimer if you need to automate tests for Windows and Internet Explorer.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There are a lot of tools out there, and what you should use depends on your team size, cross-browser testing needs, and comfort with various programming languages. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For a small team who doesn’t need cross-browser testing, I’d recommend CasperJS. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For a small team who can only write their tests in Ruby, Python, Java, or anything but Javascript for whatever reason, I’d suggest Selenium Webdriver 2 with your favorite language bindings. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For a large team with a lot of patience and cross-browser or cross-platform testing needs, I’d recommend Selenium Webdriver 2 with the various browser drivers, Ruby Bindings, and RSpec. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Only use BDD tools if you have a reason. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Only support cross-browser automated testing if you are ready to put the effort into maintaining it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Want to join our QA team? Email us at &lt;a href="mailto:devjobs@imagineeasy.com" target="_blank"&gt;devjobs@imagineeasy.com&lt;/a&gt;.&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/90475083894</link><guid>https://dev.imagineeasy.com/post/90475083894</guid><pubDate>Tue, 01 Jul 2014 14:26:00 -0400</pubDate><category>qa</category><category>testing</category><category>casperjs</category><category>selenium</category><category>test automation</category><dc:creator>asiatheqa</dc:creator></item><item><title>Learn You a Haskell for Great Good in PHP, Ruby, ...</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My main production language is PHP. I started dabbling in Haskell a couple of years ago, out of curiosity. I&amp;rsquo;ve found a few
&lt;a href="http://learnyouahaskell.com/" target="_blank"&gt;great&lt;/a&gt;
&lt;a href="http://www.seas.upenn.edu/~cis194/lectures.html" target="_blank"&gt;resources&lt;/a&gt;
&lt;a href="http://book.realworldhaskell.org/" target="_blank"&gt;out there&lt;/a&gt;
and have gone through the novice lessons a few times. I still haven&amp;rsquo;t graduated to the point of building Real Things in the language; I &lt;em&gt;have&lt;/em&gt; noticed, however, that exposure to the very different approach and style of Haskell had an immediate broadening effect on my PHP work. I encountered a great example of that yesterday.&lt;/p&gt;

&lt;h2&gt;Iterating with exceptional cases&lt;/h2&gt;

&lt;p&gt;The problem: we need to collapse a list of strings by interposing a delimiter, the classic sort of &lt;code&gt;implode()&lt;/code&gt; operation. But not all cases get the delimiter. The actual application we are building allows for different rules, but let&amp;rsquo;s treat the &amp;ldquo;no-Oxford-comma&amp;rdquo; case for the purposes of this blog post.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class RenderDelimitedTest extends \PHPUnit_Framework_TestCase
{
    public function data()
    {
        return [
            [
                [
                ],
                '',
            ],
            [
                [
                    'jim',
                ],
                'jim',
            ],
            [
                [
                    'jim',
                    'bob',
                ],
                'jim and bob',
            ],
            [
                [
                    'jim',
                    'bob',
                    'joe',
                ],
                'jim, bob and joe',
            ],
            [
                [
                    'jim',
                    'bob',
                    'joe',
                    'pete',
                ],
                'jim, bob, joe and pete',
            ],
        ];
    }

    /**
    * @dataProvider data
    * @param string[] $strings 
    * @param string $expected 
    */
    public function testRenderDelimited(array $strings, $expected)
    {
        $this-&amp;gt;assertEquals($expected, render_delimited($strings));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If we were to use a loop for this, each iteration would have to know the context of the looping in order to know whether the delimiter should be added. To me, that is both a potential breeding-ground for bugs, and ugly; I should be able to &lt;em&gt;declare&lt;/em&gt; the correct rendering for a given segment or combination of segments without reference to segments that I&amp;rsquo;m not working on.&lt;/p&gt;

&lt;h2&gt;Pattern matching and recursion&lt;/h2&gt;

&lt;p&gt;In Haskell, &lt;strong&gt;pattern matching&lt;/strong&gt; is one of the main ways to choose between alternate implementations, given your input. This problem could be solved in Haskell as follows. The function is defined with a type signature first, and then the actual function definition.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;renderDelimited :: [String] -&amp;gt; String
renderDelimited [] = ""
renderDelimited [a] = a
renderDelimited [a,b] = a ++ " and " ++ b
renderDelimited (a:theRest) = a ++ ", " ++ renderDelimited theRest
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(I&amp;rsquo;ve bastardized Haskell conventions a little for the sake of unfamiliar readers; Haskellians, forgive me!)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;renderDelimited&lt;/code&gt; function takes an array of &lt;code&gt;String&lt;/code&gt;s, and returns a &lt;code&gt;String&lt;/code&gt;. There are four cases: the empty array, a one-member array, a two-member array, and &amp;ldquo;everything else,&amp;rdquo; in the form of &amp;ldquo;&lt;code&gt;a&lt;/code&gt; merged with &lt;code&gt;theRest&lt;/code&gt;.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve applied &lt;strong&gt;recursion&lt;/strong&gt; to build the full string. Where there are three or more members, we render the first member, the delimiter, and then &lt;em&gt;the output of rendering the rest of the list with the same function.&lt;/em&gt; That&amp;rsquo;s what makes it recursive.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;*Main&amp;gt; renderDelimited []
""
*Main&amp;gt; renderDelimited ["bob"]
"bob"
*Main&amp;gt; renderDelimited ["bob", "pete"]
"bob and pete"
*Main&amp;gt; renderDelimited ["bob", "pete", "joe"]
"bob, pete and joe"
*Main&amp;gt; renderDelimited ["bob", "pete", "joe", "larry"]
"bob, pete, joe and larry"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;PHP obviously doesn&amp;rsquo;t support pattern matching in this way, but we can do the same thing with explicit conditionals. Use of the &lt;code&gt;implode()&lt;/code&gt; function allows us to merge the &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt; cases.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/**
 * @param array $strings 
 * @return string
 */
function render_delimited(array $strings)
{
    $count = count($strings);

    if ($count === 0) {
        return '';
    }

    if ($count &amp;lt; 3) {
        return implode(' and ', $strings);
    }

    return $strings[0] . ', ' . render_delimited(array_slice($strings, 1));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Boom! The tests pass.&lt;/p&gt;

&lt;p&gt;By using this technique drawn from bread-and-butter Haskell, we&amp;rsquo;ve avoided bringing the surrounding context explicitly into the iterations of a loop, and instead we are evaluating each step on its own.&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/90057727549</link><guid>https://dev.imagineeasy.com/post/90057727549</guid><pubDate>Fri, 27 Jun 2014 09:13:00 -0400</pubDate><category>functional programming</category><category>haskell</category><category>php</category><category>recursion</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Accessing undefined properties of hashes/objects (in PHP and more)</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The true focus of this post is how to retrieve given member values of associative arrays in PHP, but it will touch on analagous constructs in other popular languages, namely Java&amp;rsquo;s &lt;code&gt;Map&lt;/code&gt;, Python&amp;rsquo;s &lt;code&gt;dict&lt;/code&gt;, Ruby&amp;rsquo;s &lt;code&gt;Hash&lt;/code&gt;, and Javascript objects. The operation can be characterized as:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Given an object &lt;strong&gt;Foo&lt;/strong&gt;, if the &lt;strong&gt;Bar&lt;/strong&gt; property is set, return that; otherwise return a default value &lt;strong&gt;Default&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is such a common use case that I would expect this to have decent syntax support in any language that deals with open-ended maps such as the above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: I&amp;rsquo;m not well-versed in all of these languages, so forgive any syntax blunders or missed opportunities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BTW&lt;/strong&gt;: One of the few &amp;ldquo;features&amp;rdquo; of PHP that I genuinely hate is the blurring of the map/list distinction that is the &lt;code&gt;array&lt;/code&gt;. I&amp;rsquo;m psyched that Hack is trying to &lt;a href="http://docs.hhvm.com/manual/en/hack.collections.php" target="_blank"&gt;fix this&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Java&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Map.html#get(java.lang.Object)" target="_blank"&gt;&lt;code&gt;Map.get(key)&lt;/code&gt;&lt;/a&gt; returns the value for the requested key, or &lt;code&gt;null&lt;/code&gt; if it is not set. This has the unfortunate consequence of a logic flaw if &lt;code&gt;null&lt;/code&gt; is a possible member of the &lt;code&gt;Map&lt;/code&gt; (which is a separate can of worms). So the implementation would still have to be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo.containsKey(bar) ? foo.get(bar) : default;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Python&lt;/h2&gt;

&lt;p&gt;Python&amp;rsquo;s &lt;a href="https://wiki.python.org/moin/KeyError" target="_blank"&gt;&lt;code&gt;dict&lt;/code&gt;&lt;/a&gt; hooks us up proper. Full stop.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo.get('bar', default)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Ruby&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.ruby-doc.org/core-2.1.2/Hash.html#method-i-default" target="_blank"&gt;&lt;code&gt;Hash&lt;/code&gt;&lt;/a&gt; is a curious beast on this question. A default value can be set &lt;em&gt;on the Hash itself&lt;/em&gt; as an instance setting, rather than as part of a specific retrieval call. This works either as an argument passed to the constructor, or via the setter &lt;code&gt;#default=&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo = Hash.new(default)
# or
foo.default = default

foo[:bar]  # returns default
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Original Ruby conclusion&lt;/h3&gt;

&lt;p&gt;To me, employing that technique in this use case seems like a misleading use of that instance setting, so I would be inclined to do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo.has_key?(:bar) ? foo[:bar] : default
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Updated Ruby conclusion&lt;/h3&gt;

&lt;p&gt;Tim Morgan in the comments helpfully pointed out the method I was looking for, namely &lt;code&gt;Hash#fetch&lt;/code&gt;. So Ruby and Python are neck-and-neck:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;foo.fetch(:bar, default)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;JavaScript&lt;/h2&gt;

&lt;p&gt;JavaScript and its &lt;code&gt;undefined&lt;/code&gt; property is its own mess, so I&amp;rsquo;ll just say that JS &lt;a href="http://stackoverflow.com/a/1098955/614709" target="_blank"&gt;gives you the &lt;code&gt;in&lt;/code&gt; operator&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;("bar" in foo) ? foo.bar : default
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;PHP&lt;/h2&gt;

&lt;p&gt;Which brings us to the topic of this post. Similarly to Java, when accessing nonexistent members of an associative array in PHP, &lt;a href="http://us1.php.net/manual/en/language.types.array.php#language.types.array.syntax.accessing" target="_blank"&gt;&lt;code&gt;null&lt;/code&gt; is returned, but with an &lt;code&gt;E_NOTICE&lt;/code&gt; error&lt;/a&gt;. So, leveraging the beautiful &lt;a href="http://en.wikipedia.org/wiki/Elvis_operator" target="_blank"&gt;Elvis operator&lt;/a&gt; (one of my favorite syntactic sugar cubes), we get:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$foo['bar'] ?: $default  // throws E_NOTICE
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To bypass the logic flaw of the &lt;code&gt;null&lt;/code&gt;, we &amp;ldquo;can often assume&amp;rdquo; that &lt;code&gt;null&lt;/code&gt; is not a possible value for the array in question. I had (or saw someone employ) the brilliant idea of using PHP&amp;rsquo;s error suppression operator, &lt;code&gt;@&lt;/code&gt;, to make this behave like the Java version, i.e. not throw the &lt;code&gt;E_NOTICE&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@$foo['bar'] ?: $default  // E_NOTICE is suppressed
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Obviously suppressing errors is a controversial matter. Some would argue that it&amp;rsquo;s altogether poor style. It&amp;rsquo;s also a slippery slope, especially in a team setting: this is the only scenario where I would consider using &lt;code&gt;@&lt;/code&gt;, but it&amp;rsquo;s hard to enforce that discipline across a team. So, I posted this solution on our team chat for feedback.&lt;/p&gt;

&lt;p&gt;We are fortunate enough to have &lt;a href="https://twitter.com/naderman" target="_blank"&gt;Nils Adermann&lt;/a&gt; on our team, and he weighed in with some more fundamental concerns, aside from the question of code style.&lt;/p&gt;

&lt;h3&gt;The bad&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Imagine the &lt;code&gt;@$params&lt;/code&gt; being an array access object which triggers autoloading in one of its functions; then &lt;code&gt;@$params['foo']&lt;/code&gt; would hide parse errors in those PHP files. So it&amp;rsquo;s a generally bad idea, since you can never be quite certain what else you are accidently silencing in addition to what you mean to silence.&lt;/p&gt;
  
  &lt;p&gt;Furthermore, &lt;code&gt;@&lt;/code&gt; is actually slow, since it triggers the error, jumps into the error handler, executes code there to figure out it&amp;rsquo;s supposed to be silent, and only then returns back to the original code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ha! So, to address the first concern, if we are disciplined we can only use this practice on the sorts of plain &lt;code&gt;string =&amp;gt; string&lt;/code&gt; arrays that had conceived of; but that doesn&amp;rsquo;t solve the performance concern. And it requires discipline.&lt;/p&gt;

&lt;h3&gt;The alternative&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;re also fortunate to have &lt;a href="https://twitter.com/r_wos" target="_blank"&gt;Richard Wossal&lt;/a&gt; on board. He pointed out a function library that provides this functionality: &lt;a href="https://github.com/igorw/get-in" target="_blank"&gt;igorw/get-in&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;\igorw\get_in($foo, ['bar'], $default);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is clunkier than my ill-conceived PHP version, or the Python version, but it does what we need. Additionally, as of &lt;a href="http://www.php.net//manual/en/migration56.new-features.php#migration56.new-features.use" target="_blank"&gt;PHP 5.6&lt;/a&gt;, we can &lt;code&gt;import&lt;/code&gt; functions, so this would become that much more fluid (without the inline fully-qualified name).&lt;/p&gt;

&lt;p&gt;The use of this function together with anonymous functions also lends itself to creative local solutions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function extractParts(array $data)
{
    $part = function ($key) use ($data) {
        return \igorw\get_in($data, [$key]);
    };

    return [
        $part('family'),
        $part('given'),
        $part('suffix'),
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This was a really nice way to explore the powers and limitations of this data structure in various languages, and seeing the implications of pushing those limits. It was also a good illustration of how ideas that smell questionable, very likely are questionable.&lt;/p&gt;

&lt;h2&gt;Addendum&lt;/h2&gt;

&lt;p&gt;Here&amp;rsquo;s my interpretation of Go, using the &amp;ldquo;comma ok&amp;rdquo; double-return-value idiom:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if bar, ok := foo["bar"]; ok {
    return bar
} else {
    return default
}
&lt;/code&gt;&lt;/pre&gt;</description><link>https://dev.imagineeasy.com/post/89912077319</link><guid>https://dev.imagineeasy.com/post/89912077319</guid><pubDate>Wed, 25 Jun 2014 20:45:00 -0400</pubDate><category>php</category><category>syntax</category><category>language comparison</category><category>data structures</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Defining Communication in WebSocket Applications with WAMP</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In &lt;a href="http://dev.imagineeasy.com/post/88665904539/websockets-vs-ajax-an-initial-comparison" target="_blank"&gt;an earlier investigation&lt;/a&gt;, I conducted a very high-level comparison of WebSockets to AJAX. I discovered that WebSockets, with its inherently persistent connection, makes more sense in principle for a low-latency interactive application, but that there is no built-in semantic for requests and responses in the way that AJAX inherits from HTTP. Enter the &lt;a href="http://www.wampserver.com/" target="_blank"&gt;ill-named&lt;/a&gt; protocol of &lt;a href="http://wamp.ws/" target="_blank"&gt;WAMP&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Web Application Messaging Protocol (WAMP)&lt;/h2&gt;

&lt;p&gt;Boom. This is pretty much exactly what I had been looking for. WAMP (&lt;a href="http://wamp.ws/" target="_blank"&gt;http://wamp.ws/&lt;/a&gt;) is a subprotocol of WebSockets, in that it specifies a communication semantic for messages sent over WebSockets.&lt;/p&gt;

&lt;p&gt;WAMP identifies two planes of communication (two &amp;ldquo;patterns&amp;rdquo;): informational messages and commands. Messages can be sent (&amp;ldquo;published&amp;rdquo;) and listened for (&amp;ldquo;subscribed to&amp;rdquo;), which WAMP calls the &amp;ldquo;PubSub&amp;rdquo; pattern. Commands can also be issued (&amp;ldquo;called&amp;rdquo;), implemented, and responded to. WAMP refers to this as the pattern of &amp;ldquo;RPC,&amp;rdquo; Remote Procedure Call.&lt;/p&gt;

&lt;p&gt;In this scheme, a middle layer (&amp;ldquo;Router&amp;rdquo;) is introduced between sending and receiving parties (&amp;ldquo;Clients&amp;rdquo;). Each Client (e.g. a browser or application server) can register itself with the Router as subscribing to a certain message type, or implementing a certain procedure type. The Router is responsible for receiving messages, distributing them to the appropriate Clients, &lt;em&gt;and&lt;/em&gt; responding to or acknowledging most messages in a sensible way.&lt;/p&gt;

&lt;p&gt;The Router with the Clients are referred to collectively as &amp;ldquo;Peers.&amp;rdquo;&lt;/p&gt;

&lt;h2&gt;Use in a typical web application&lt;/h2&gt;

&lt;p&gt;So in the case of a real-time collaborative web application, each user&amp;rsquo;s browser would register itself as a listener to the appropriate message types, and each application server would register itself as a provider of the appropriate procedure calls, and possibly messages as well. So to represent a user joining the chat room called &amp;ldquo;WampChat&amp;rdquo; and sending a message, the flow might look like this:&lt;/p&gt;

&lt;h3&gt;Browser which is joining, contacts router&lt;/h3&gt;

&lt;ul&gt;&lt;li&gt;12345 is a session ID generated by the server&lt;/li&gt;
&lt;li&gt;44978 is a request ID generated by the browser&lt;/li&gt;
&lt;li&gt;64621 is a publication ID generated by the server&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Flow:&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Browser: &lt;code&gt;["HELLO", "com.example.chat", {}]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Router: &lt;code&gt;["WELCOME", 12345, {}]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Browser: &lt;code&gt;["PUBLISH", 44978, {}, "com.example.chat.joinroom", [], {"user":"bilbo", "room":"WampChat"}]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Router: &lt;code&gt;["PUBLISHED", 44978, 64621]&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;h3&gt;Router broadcasts join event&lt;/h3&gt;

&lt;ul&gt;&lt;li&gt;78945 is the &amp;ldquo;joinroom&amp;rdquo; subscriber ID of a browser already connected to the room&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Server: &lt;code&gt;["EVENT", 78945, 64621, {"user":"bilbo", "room":"WampChat"}]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;Browser requests that a user be kicked&lt;/h3&gt;

&lt;ul&gt;&lt;li&gt;34236 is the request ID for the post, generated by the browser&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Browser: &lt;code&gt;["CALL", "com.example.chat.kickuser", 34236, {}, [], {"room":"WampChat", "user":"trollza987"}]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;Router requests fulfillment of the kick&lt;/h3&gt;

&lt;ul&gt;&lt;li&gt;89731 is the registration ID of a server already connected to handle &amp;ldquo;kickuser&amp;rdquo; calls&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Router: &lt;code&gt;["INVOCATION", 34236, 89731, {}, [], {"room":"WampChat", "user":"trollza987"}]&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;Server performs, and result is sent back to browser&lt;/h3&gt;

&lt;ol&gt;&lt;li&gt;Server: &lt;code&gt;["YIELD", 34236, {}, ["OK"]]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Router: &lt;code&gt;["RESULT", 34236, {} ["OK"]]&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;h2&gt;Load balancing the routers&lt;/h2&gt;

&lt;p&gt;One thing I&amp;rsquo;m not sure about is how to load-balance Routers. As far as the other Peers are concerned, there is one endpoint for the Router that they need to deal with, so registering listeners and RPC-handlers with a given Router instance means that all Router instances need to be made aware of this. It might be done via a shared Memcached or Redis instance, as in this very ominously stormy diagram:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://66.media.tumblr.com/62fb778f07d770b2b56513f7f86c6590/tumblr_inline_n7f88m7Hla1qhp1cd.png" alt="Clustered WAMP Architecture diagram"/&gt;&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/89263521964</link><guid>https://dev.imagineeasy.com/post/89263521964</guid><pubDate>Thu, 19 Jun 2014 10:59:00 -0400</pubDate><category>websocket</category><category>wamp</category><category>server</category><category>cluster</category><category>devops</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>WebSockets vs. AJAX: an initial comparison</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At ImagineEasy, we are starting on a large new product, with a significant frontend component. We have agreed on the idea of a single-page JavaScript application, but we aren&amp;rsquo;t sure about whether to use AJAX or WebSockets for the underlying client-server communications; so I decided to put together a high-level comparison. Disclaimer: I have mostly backend experience, and almost no SPA projects under my belt; so I probably have blind spots here.&lt;/p&gt;

&lt;h2&gt;Browser support&lt;/h2&gt;

&lt;p&gt;There is no support for WebSockets in IE before IE10 (as well as older versions of other browsers), so if you are committed to supporting those users, you won&amp;rsquo;t be able to use WebSockets.&lt;/p&gt;

&lt;h2&gt;Server support&lt;/h2&gt;

&lt;p&gt;WebSockets require a dedicated process independent of the HTTP server, for handling the WebSocket traffic. If you have HTTP and WebSocket on the same box, it will require a reverse proxy to allow both to listen on port 80. Using WebSockets also requires an implementation in the programming language you are using, with all of the knowledge, ops, and maintenance costs that go along with that.&lt;/p&gt;

&lt;h2&gt;Statefulness&lt;/h2&gt;

&lt;p&gt;WebSockets are stateful by nature; the browser-server connection is held open throughout the user&amp;rsquo;s session, allowing both browser and server to push data to the other party. This means there is no need for special handling to reconstruct session-stateful data, such as a memcached server to share session state among servers in an AJAX cluster. It&amp;rsquo;s also unnecessary to destroy sessions with WebSockets, as the close of the connection is in itself destruction of the session.&lt;/p&gt;

&lt;h2&gt;Message semantics&lt;/h2&gt;

&lt;p&gt;AJAX inherits a number of message semantics from HTTP which have no analogue in WebSockets. Because HTTP uses URLs, requests are inherently namespaced in an implied hierarchical structure. The WebSocket protocol simply specifies a string or binary blob, leaving it up to the implementation to specify &amp;ldquo;locations&amp;rdquo; to act upon. HTTP also provides a framework for responding to requests with standard status codes; in WebSockets, a server-client message is not even inherently identified as a response, so it&amp;rsquo;s up to the implementation to flag a message as the response to an earlier received message, and to impose a system of indicating &amp;ldquo;error&amp;rdquo; vs. &amp;ldquo;OK&amp;rdquo; status, etc. Finally, HTTP headers provide a convention for attaching metadata to messages.&lt;/p&gt;

&lt;h2&gt;Data typing&lt;/h2&gt;

&lt;p&gt;In both AJAX and WebSockets, the actual data payload is untyped, being either a string or plain binary. The application must establish its own convention of type and its enforcement (e.g. JSON Schema).&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;That&amp;rsquo;s the skinny on our initial overview of AJAX vs. WebSockets. I would love to see a convention evolve for providing some of those missing features to WebSockets. I did find &lt;a href="http://new-bamboo.co.uk/blog/2010/02/10/json-event-based-convention-websockets" target="_blank"&gt;a post from New Bamboo&lt;/a&gt; which seems like an embryonic form of that, but I&amp;rsquo;m surprised I didn&amp;rsquo;t find more. Let me know if I&amp;rsquo;m missing something!&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/88665904539</link><guid>https://dev.imagineeasy.com/post/88665904539</guid><pubDate>Fri, 13 Jun 2014 09:46:00 -0400</pubDate><category>ajax</category><category>frontend</category><category>websocket</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Why Laravel Homestead Makes Me Nervous</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/YitzOfTheBits" target="_blank"&gt;Yitzchak Schaffer (@YitzOfTheBits)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had an immediate negative reaction to the news of Laravel&amp;rsquo;s new Homestead program. In &lt;a href="http://laravel.com/docs/homestead?version=4.2#introduction" target="_blank"&gt;their own words&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Laravel Homestead is an official, pre-packaged Vagrant &amp;ldquo;box&amp;rdquo; that provides you a wonderful development environment without requiring you to install PHP, a web server, and any other server software on your local machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For starters, part of my reaction was due to my irritation at all the marketing that Laravel has been pushing out regarding an upcoming announcement, which I presume referred to Homestead, and Forge, their new hosting solution. My perception of that as hype, in addition to the not-terribly-innovative nature of this huge revelation, didn&amp;rsquo;t dispose me well to the announcement.&lt;/p&gt;

&lt;p&gt;In truth, I can see how the availability of this pre-built development platform will be a tremendous boon to a lot of Laravel users.&lt;/p&gt;

&lt;p&gt;Now that I&amp;rsquo;ve had a chance to get past the initial emotional reaction, I can start to analyze the more objective reasons this project bothers me.&lt;/p&gt;

&lt;h2&gt;When I was your age&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ve been doing web development with PHP for about 6 years. In that time, I&amp;rsquo;ve bootstrapped my knowledge of Linux in general, and running servers in particular. I learned, from the ground up, all about configuring Ubuntu servers, including using Puppet for management. Since I joined the Imagine Easy team in January, I&amp;rsquo;ve added some experience with cloud virtual-server hosting and deployment.&lt;/p&gt;

&lt;p&gt;This in-the-trenches learning is both a reflection of my natural mode of &amp;ldquo;dive in there and figure it all out,&amp;rdquo; and a reinforcement of it. Most of my experience has come with the luxury of time and resources to just dig in and get to know different ways of solving problems in a given space. This means that I value getting my hands dirty with all different parts of the system, and having a hand in setting everything up.&lt;/p&gt;

&lt;p&gt;The notion of a pre-built environment is a challenge to that perspective. Whereas I try to get as much perspective and knowledge as I can to inform decisions about my stack, I see Homestead as taking that away from developers. This means they are trained to delegate decision-making, as well as losing the actual knowledge and in-depth experience they might have gotten by being thrown in the deep end.&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;fully acknowledge&lt;/em&gt; that this is not a complete nor totally fair assessment of Homestead; but this outlook greatly influenced the light in which I see Homestead.&lt;/p&gt;

&lt;h2&gt;The Laragarden&lt;/h2&gt;

&lt;blockquote class="twitter-tweet" lang="en"&gt;&lt;p&gt;&lt;a href="https://twitter.com/yitznewton" target="_blank"&gt;@yitznewton&lt;/a&gt; Laragarden&lt;/p&gt;— Michael Hasselbring (@mikelbring) &lt;a href="https://twitter.com/mikelbring/statuses/467059489405812736" target="_blank"&gt;May 15, 2014&lt;/a&gt;&lt;/blockquote&gt;

&lt;script async src="//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;&lt;p&gt;A more serious argument against buying into Homestead is the notion of platform dependency. Over the last two years, Robert C. Martin (&amp;ldquo;Uncle Bob&amp;rdquo;) has been by far the greatest influence on my thinking. One of his mantras (see &lt;a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html" target="_blank"&gt;Clean Architecture&lt;/a&gt;) is maintaining independence from things that you don&amp;rsquo;t control. In the context of frameworks, it means isolating your business logic from the framework in discrete, Plain Old Object code. One immediate benefit of this is that the core logic is easier to test, being separated from any framework plumbing. A second is that, when the framework inevitably changes, you are not forced to make painful changes in the midst of your application; instead, all that&amp;rsquo;s necessary is to write the boundary layer that connects your free-floating business code to the framework.&lt;/p&gt;

&lt;p&gt;The same concept applies to other components of the stack. If you hard-code persistence into your core code in terms of (MySQL|MongoDB|ActiveRecord|Redis) or whatever, and mix business logic in the same place as persistence, you are stuck with that decision, unless you want to rewrite it.&lt;/p&gt;

&lt;p&gt;Using a full-stack boxed solution like Homestead encourages that sort of thinking. I acknowledge 100% that it doesn&amp;rsquo;t &lt;em&gt;force&lt;/em&gt; the behavior of lazily (or unwittingly) coupling these external elements into your application, but it almost implies that is the way to go.&lt;/p&gt;

&lt;h2&gt;Down the road&lt;/h2&gt;

&lt;p&gt;Furthermore, let&amp;rsquo;s say an application grows, and requires a particular piece added to the stack &amp;ndash; Solr search, perhaps. How easy will it be to add those components? Will the knowledge gap fostered by Homestead bite the project developers now that they need to extend the stack? You run into the same fragility problem where decisions made by the Homestead team down the road may conflict with your local emendments to the build.&lt;/p&gt;

&lt;p&gt;The project&amp;rsquo;s documentation also &lt;a href="http://laravel.com/docs/homestead?version=4.2#daily-usage" target="_blank"&gt;indicates&lt;/a&gt; that running multiple Laravel applications on a single Homestead instance is the normal mode of operation; that seems to indicate that the Homesteaders are not taking project-specific build modifications into account.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I am confident that Laravel Homestead will help a lot of people, and I am grateful to the entire Laravel enterprise as a key player in the continuing maturation of the PHP community. I have tried to highlight what I see as the key shortcoming of Homestead, and why I believe sober discretion is required in using such a pre-boxed solution.&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/86116559974</link><guid>https://dev.imagineeasy.com/post/86116559974</guid><pubDate>Sun, 18 May 2014 12:04:00 -0400</pubDate><category>laravel</category><category>devops</category><category>architecture</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Introducing travis-artifacts.php</title><description>&lt;p&gt;At Imagine Easy, we pride ourselves on building great products on a great foundation. A great foundation means to also focus on code quality, and with said quality, the right amount of tests and (of course) coding standards.&lt;/p&gt;

&lt;h3&gt;Travis-CI&lt;/h3&gt;

&lt;p&gt;For continuous integration and continuous delivery, we&amp;rsquo;re hugely invested in a platform called &lt;a href="http://travis-ci.com" target="_blank"&gt;Travis-CI&lt;/a&gt;. At the very minimum Travis-CI allows us to run tools like phpunit and php codesniffer on code pushes. On successful builds (and merges) it also hooks into our in-house continuous deployment service (to be show-cased later :)).&lt;/p&gt;

&lt;p&gt;Travis-CI is a hosted service — it&amp;rsquo;s in the cloud. When code is pushed, a VM is started and our tooling is run.&lt;/p&gt;

&lt;p&gt;In order to keep track of improvements and regressions, we utilize a rubygem called &lt;code&gt;travis-artifacts&lt;/code&gt;, which allows anyone to store reports generated on &lt;a href="http://aws.amazon.com/s3/" target="_blank"&gt;Amazon S3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;travis-artifacts&lt;/code&gt; is a neat &lt;em&gt;little&lt;/em&gt; tool, however, it comes with a not so small ruby dependency called Nokogiri.&lt;/p&gt;

&lt;p&gt;Nokogiri is an XML parser which is probably used inside &lt;code&gt;travis-artifacts&lt;/code&gt; or one of its dependencies when they talk to the Amazon APIs to store files on Amazon S3.&lt;/p&gt;

&lt;h3&gt;Nokogiri&lt;/h3&gt;

&lt;p&gt;Nokogiri is about 150 MB once installed and needs to be downloaded &lt;strong&gt;and compiled&lt;/strong&gt; during each test run, which implies a considerable slowdown and essentially build backlog when we try to advance.&lt;/p&gt;

&lt;p&gt;Since most (if not all) our builds run in a PHP environment, we decided to improve this situation.&lt;/p&gt;

&lt;h2&gt;travis-artifacts.php&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;travis-artifacts.php&lt;/strong&gt; - &lt;a href="https://github.com/easybiblabs/travis-artifacts.php" target="_blank"&gt;https://github.com/easybiblabs/travis-artifacts.php&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code is free for use (and open-sourced under a simplified BSD license). We try to mimic the API of the travis-artifacts tool. In a nutshell, here&amp;rsquo;s how you integrate it into your PHP project:&lt;/p&gt;

&lt;p&gt;Because the tool is available through &lt;a href="https://packagist.org/packages/easybib/travis-artifacts" target="_blank"&gt;packagist&lt;/a&gt;, you add the following to your &lt;code&gt;composer.json&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "require-dev": {
    "easybib/travis-artifacts": "~0.2.0" 
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On Travis-CI, ensure development dependencies are installed (in &lt;code&gt;.travis.yml&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;before_script: composer install --dev --prefer-dist
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To publish build artifacts, add the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;after_script: ./vendor/bin/travis-artifacts --path=results --root=/home/travis
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This &lt;em&gt;assumes&lt;/em&gt; that the results from your tools are stored in a results directory.&lt;/p&gt;

&lt;p&gt;Along with these modifications to your &lt;code&gt;.travis.yml&lt;/code&gt;, our tool expects/uses the following environment variables. In case you have not used &lt;code&gt;travis-artifacts&lt;/code&gt; before, the following is also required:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  global:
    - ARTIFACTS_S3_BUCKET=your_aws_s3_bucket
    - ARTIFACTS_AWS_ACCESS_KEY_ID=your_aws_key
    - ARTIFACTS_AWS_SECRET_ACCESS_KEY=your_aws_secret
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So simple! :) So easy(bib)!&lt;/p&gt;

&lt;h2&gt;Fin&lt;/h2&gt;

&lt;p&gt;In summary, we saw between 1 to 2 minute faster builds. Since we try to keep our builds fast (and usually under 5 minutes), this is a hefty improvement!&lt;/p&gt;

&lt;p&gt;We hope the code is useful to others.&lt;/p&gt;

&lt;p&gt;All feedback and pull requests are always very welcome.&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/85122094424</link><guid>https://dev.imagineeasy.com/post/85122094424</guid><pubDate>Thu, 08 May 2014 10:28:27 -0400</pubDate><category>php</category><category>travis-ci</category><category>testing</category><category>code-quality</category><dc:creator>tillinside-blog</dc:creator></item><item><title>Cleaning Code As You Go</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/yitznewton" target="_blank"&gt;Yitzchak Schaffer (@yitznewton)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As one of the first steps in a major new feature we are working on for EasyBib, we needed to introduce some polymorphism into the application. The polymorphic class was already implemented in another product; all that we needed to do was refactor the existing implementation to swap in the new polymorphic version.&lt;/p&gt;

&lt;p&gt;In the course of doing this in a ~300-line pull request, we were able to make a number of Clean Code improvements to the one class involved:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;Remove an unused instance variable, which had been originally added in anticipation of functionality that never materialized&lt;/li&gt;
&lt;li&gt;Remove commented-out code&lt;/li&gt;
&lt;li&gt;Replace magic values with a named constant&lt;/li&gt;
&lt;li&gt;Improve variable names dramatically&lt;/li&gt;
&lt;li&gt;Add temporary, placeholder variables to make intent more clear&lt;/li&gt;
&lt;li&gt;Refactor business logic out of the web controller and into its own POPO class, with minimal dependencies&lt;/li&gt;
&lt;li&gt;Move variable declarations closer to where the variables are used&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Additionally, we replaced some very old-school loop-based building of data arrays with &lt;code&gt;array_map()&lt;/code&gt; and &lt;code&gt;array_reduce()&lt;/code&gt; calls.&lt;/p&gt;

&lt;p&gt;We have a long way to go, but these are some wonderful steps toward an ever-cleaner codebase.&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/84553480894</link><guid>https://dev.imagineeasy.com/post/84553480894</guid><pubDate>Fri, 02 May 2014 17:39:00 -0400</pubDate><category>Clean Code</category><category>refactoring</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Maintaining Clean Boundaries</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/yitznewton" target="_blank"&gt;Yitzchak Schaffer (@yitznewton)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of Uncle Bob&amp;rsquo;s pieces of advice in &lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank"&gt;Clean Code&lt;/a&gt;, is to protect the boundaries of your codebase from change. In practical terms, this means insulating the use of third-party libraries in your codebase by wrapping them in an adapter interface.&lt;/p&gt;

&lt;p&gt;We use &lt;a href="http://docs.guzzlephp.org/en/latest/" target="_blank"&gt;Guzzle&lt;/a&gt; extensively in our products, particularly our &lt;a href="https://github.com/easybiblabs/oauth2-client-php" target="_blank"&gt;OAuth2 client&lt;/a&gt;. Guzzle is an excellently-designed HTTP client library for PHP. I actually contemplated using a wrapper when first starting a couple of new projects with Guzzle, but the fact of its great design led me to believe that this was unnecessary.&lt;/p&gt;

&lt;p&gt;The release of Guzzle 4 showed how I was wrong. The essential structure is very similar to Guzzle 3, but interfaces and namespaces have changed, meaning that I now need to completely rewrite the tests and implementation for all the integration points throughout our products. If I had gone with the adapter layer, I could have simply written a new adapter, and the integration points would have remained unchanged.&lt;/p&gt;

&lt;p&gt;Isolate your boundaries with adapter interfaces!&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/80693884643</link><guid>https://dev.imagineeasy.com/post/80693884643</guid><pubDate>Tue, 25 Mar 2014 14:20:00 -0400</pubDate><category>Clean Code</category><category>open source</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Test-Driven Development in Context</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/yitznewton" target="_blank"&gt;Yitzchak Schaffer (@yitznewton)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This article comes in response to &lt;a href="http://dev.imagineeasy.com/post/79356891740/test-driven-development-is-not-the-solution" target="_blank"&gt;a critique of TDD&lt;/a&gt; eloquently advanced by my colleague, &lt;a href="http://r-wos.org/" target="_blank"&gt;Richard Wossel&lt;/a&gt;. Rather than offer a point-by-point comparison of our perspectives, I am going to paint TDD in a broader context, and I hope that this will clarify its value as I see it.&lt;/p&gt;

&lt;p&gt;The most essential aspect of my practice of TDD to me, is that it &lt;em&gt;works&lt;/em&gt; when I create software in this way. I look at my output, and I see that the quality improves when I test-drive. I have a better understanding of the process and the product. I also prevent myself from introducing bugs, and catch edge cases up front that would have needed post-hoc analysis to identify and correct. My code is better insofar as TDD makes me think more carefully about what I am doing, in order to write correct and comprehensive tests. This alone justifies the practice to me.&lt;/p&gt;

&lt;p&gt;So what is TDD? I find it useful to think of it in terms of &lt;em&gt;Behavior-Driven Development&lt;/em&gt;. Like &lt;a href="http://programmers.stackexchange.com/users/13181/mike-brown" target="_blank"&gt;Mike Brown&lt;/a&gt; and subsequent commenters on &lt;a href="http://programmers.stackexchange.com/a/135246/42950" target="_blank"&gt;this Programmers Stack Exchange answer&lt;/a&gt;, I see BDD as nothing more than a clearer
restatement of Test-Driven Development. TDD represents a focus on defining and measuring behavior of the &lt;em&gt;system under test (SUT)&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Example application&lt;/h2&gt;

&lt;p&gt;We have a product to build; let&amp;rsquo;s say that it is the web service API behind a mobile check-in app. We have decided on a framework, and are ready to begin development. How do we proceed? What guides us through the process of building the application? We should start by considering the response we get back from the API for a checkin. We expect that the response code will be 201, the body will consist of a particular JSON status, and the &lt;code&gt;Content-Type&lt;/code&gt; header will correspond to this.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Given I have a logged-in user
When I receive a POST to /checkins/ with {lat: 23.45, lng: 98.76}
I should respond with a 201 status
And I should include the Content-Type header of application/json
And I should include a response body of {"status":"ok"}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sound and look like acceptance tests? Exactly! TDD and &amp;ldquo;acceptance&amp;rdquo; tests intersect at this highest level. We can write those tests now, and if we need to, defer writing the implementation, marking them incomplete as we drill down into the application. For the sake of this post, I am going to assume that we have taken care of the &amp;ldquo;logged-in user&amp;rdquo; requirement. We can make this test pass easily enough (use your imagination with regard to the framework):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function createAction()
{
    return (new Response())
        -&amp;gt;setStatus(201)
        -&amp;gt;setContentType('application/json')
        -&amp;gt;setBody(json_encode(['status' =&amp;gt; 'ok'])
        ;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;rsquo;s consider the case of invalid coordinates. Assume we have built the above case already, with a &lt;code&gt;CheckinController&lt;/code&gt; which has a &lt;code&gt;create&lt;/code&gt; action. Here&amp;rsquo;s an abbreviated test:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;When I receive a POST to /checkins/ with {lat: foo, lng: 123.4}
I should respond with a 400 status
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When we start writing the &lt;code&gt;CheckinController:create&lt;/code&gt; action, we discover that some code somewhere needs to know about valid and invalid coordinates. For the sake of passing the tests, we could place that in the controller, and extract to its own class later. With the following, we should be able to make the above tests pass:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function createAction()
{
    $coordinates = $this-&amp;gt;request-&amp;gt;getParams();

    if (!$this-&amp;gt;validateCoordinates($coordinates)) {
        return (new Response())
            -&amp;gt;setStatus(400)
            ;
    }

    return (new Response())
        -&amp;gt;setStatus(201)
        -&amp;gt;setContentType('application/json')
        -&amp;gt;setBody(json_encode(['status' =&amp;gt; 'ok'])
        ;
}

private function validateCoordinates(array $coordinates)
{
    if (!is_float($coordinates['lat'])) {
        return false;
    }

    return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This would be a good time to extract that validation into its own class &amp;ndash; the &amp;ldquo;refactor&amp;rdquo; step of the &amp;ldquo;red-green-refactor&amp;rdquo; cycle. Now arriving at the creation of a coordinate validator, we have the ideal opportunity to do our initial thinking about edge cases. We can leave our 400 error test above to test controller behavior, and bring the case itself down as the first unit test for the validator:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;When I receive a latitude which is a string and a longitude which is a float
Then I should return false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since we need concrete test cases, we will need to choose specific values, being careful that there are no assumptions which gloss over further &amp;ldquo;typey&amp;rdquo;  edge cases, such as floating-point math slop, truthy-falsy inconsistencies, and the like. Here we translate this test into xUnit syntax:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$this-&amp;gt;assertFalse($validator-&amp;gt;validate(['lat' =&amp;gt; 'foo', 'lng' =&amp;gt; 123.4]));
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Analysis&lt;/h2&gt;

&lt;p&gt;Based on these examples, we can derive some conclusions about TDD. Firstly, it is not inherently about the &amp;ldquo;unit.&amp;rdquo; The focus can be anything from a minor subsystem responsible for validating a particular type of input, to the entire application. It&amp;rsquo;s also not specifically about finding or preventing bugs. The goal is ensuring that you have defined exactly what your unit of code is supposed to &lt;em&gt;do&lt;/em&gt; before writing it, and that the code in fact &lt;em&gt;does those things, and nothing else.&lt;/em&gt; It&amp;rsquo;s a general set of practices that informs the development process for all levels of an application.&lt;/p&gt;

&lt;p&gt;TDD carries several immediate design benefits. Firstly, it uses human nature to push the developer to manage dependencies and coupling. The insistence on testability means that we need to set up each system for testing. The more dependencies a SUT has, the more irritating the process of building and maintaining the tests. The ongoing frustration that comes with having to manage excessive dependencies helps spur the developer to appropriately divide responsibilities. This leads to the system being flexible enough to accomodate future growth and changes in the application, and &lt;em&gt;this&lt;/em&gt; is a direct design benefit of TDD.&lt;/p&gt;

&lt;p&gt;Secondly, because all changes must be preceded by tests, it follows that, if a behavior cannot be tested, it cannot be incorporated into the system. This ensures that the magical and mystical, along with their attendant mystical bugs, will be absent.&lt;/p&gt;

&lt;p&gt;An additional design benefit results from the outside-in behavioral orientation that I have assumed. Because we always look at a system under test from the perspective of the consumer of that system, we are more attuned to considerations of interface, which helps us choose better names. We also get direct and immediate feedback on the way we have structured the divisions between subsystems.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I am not a strict TDD practitioner (yet), but I have been working these techniques into my coding over the past several years, and I am still learning and refining them. I do it because I perceive the benefit in the code I create. I would consider my main mentor in this to be &lt;a href="http://blog.8thlight.com/uncle-bob/archive.html" target="_blank"&gt;Uncle Bob Martin&lt;/a&gt;, via his writings. I encourage anyone with further interest to read the excellent material on TDD in his classic &lt;a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445" target="_blank"&gt;Agile Software Development, a.k.a. &amp;ldquo;the PPP book&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Epilogue&lt;/h2&gt;

&lt;p&gt;I used a pseudo-framework for the examples above, but the outside-in design methodology could apply here also: we could continue on building the framework itself based on the interface decisions brought on by our demo application.&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/80679930939</link><guid>https://dev.imagineeasy.com/post/80679930939</guid><pubDate>Tue, 25 Mar 2014 11:02:00 -0400</pubDate><category>TDD</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Turning Comments into Code</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/yitznewton" target="_blank"&gt;Yitzchak Schaffer (@yitznewton)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was just reading in &lt;a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882" target="_blank"&gt;Clean Code&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The proper use of comments is to compensate for our failure to express ourself in code. Note that I used the word failure. I meant it. Comments are always failures. We must have them because we cannot always figure out how to express ourselves without them, but their use is not a cause for celebration. So when you find yourself in a position where you need to write a comment, think it through and see whether there isn’t some way to turn the tables and express yourself in code. Every time you express yourself in code, you should pat yourself on the back. Every time you write a comment, you should grimace and feel the failure of your ability of expression.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The day after I read this, I had to modify some code in our API. My initial pass looked like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if (!$user) {
    // this must be a guest user

    return [
        'id' =&amp;gt; $userId,
        'first' =&amp;gt; null,
        'last' =&amp;gt; null,
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I was reminded of Uncle Bob&amp;rsquo;s advice, and restructured the code into this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if (!$user) {
    return self::getGuestUser($userId);
}

// ...

private static function getGuestUser($userId)
{
    return [
        'id' =&amp;gt; $userId,
        'first' =&amp;gt; null,
        'last' =&amp;gt; null,
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instant ROI gratification on that chapter! How&amp;rsquo;s that for expressive code?&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/79371224092</link><guid>https://dev.imagineeasy.com/post/79371224092</guid><pubDate>Wed, 12 Mar 2014 13:13:00 -0400</pubDate><category>refactoring</category><category>clean code</category><category>comments</category><dc:creator>yitznewton-blog</dc:creator></item><item><title>Test Driven Development is not the solution</title><description>&lt;p&gt;&lt;em&gt;This is the first of a set of posts representing different viewpoints on Test Driven Development.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;by &lt;a href="http://r-wos.org/" target="_blank"&gt;Richard Wossal&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s hard to argue against TDD because that is often construed as arguing against software testing itself.&lt;/p&gt;
&lt;p&gt;I guess there are actually people who think that &lt;em&gt;all testing&lt;/em&gt; is bollocks, but I am not one of them. I think that there&amp;rsquo;s value in regression and acceptance testing. Yet I still think that TDD is absolutely the wrong way to go. I&amp;rsquo;ll try and explain that opinion.&lt;/p&gt;
&lt;p&gt;I will try and &lt;em&gt;not&lt;/em&gt; bring up any arguments that boil down to &amp;ldquo;if you&amp;rsquo;re being stupid, TDD doesn&amp;rsquo;t help&amp;rdquo;. Sometimes people claim that TDD makes software development easier. But &amp;ldquo;easy&amp;rdquo; is a big concept and I assume they don&amp;rsquo;t mean &amp;ldquo;follow that one weird trick and your programs will always work&amp;rdquo;. Nobody can expect any software development technique to help &lt;em&gt;so much&lt;/em&gt; that you can switch your brain off - and I don&amp;rsquo;t expected that from TDD.&lt;/p&gt;
&lt;p&gt;The object of TDD is the unit, and the unit test. That is not necessarily always true, one could theoretically do test driven development against higher-level functional tests. But since one of the claims pro TDD is that it makes the code itself better, and since we write programs by typing in one unit of code after another (roughly), I think it&amp;rsquo;s fair to say that the unit is the canonical choice for TDD.&lt;/p&gt;
&lt;p&gt;So TDD starts out with a simple test. That test fails, so then there&amp;rsquo;s code being written to satisfy the test. Then add another test and so on.&lt;/p&gt;
&lt;p&gt;The usual claim is that, by going by that method, you&amp;rsquo;re going to end up with a testable (hence well-designed), and well-tested unit of code.&lt;/p&gt;
&lt;p&gt;In my opinion there are a few things wrong with that claim.&lt;/p&gt;
&lt;p&gt;First, &lt;strong&gt;testable does not equal well-designed&lt;/strong&gt;. In fact, testability and well-designed-ness of code are completely orthogonal. Yes, an easily unit-testable class is probably better than &lt;em&gt;the same class&lt;/em&gt; with a design that prohibits unit-testing. But it&amp;rsquo;s only exactly that.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;
&lt;p&gt;The class might be completely unnecessary. This is a particularly common oversight. The functionality might already exist elsewhere. Or the class might just not &lt;em&gt;do anything&lt;/em&gt; worthwhile at all. TDD doesn&amp;rsquo;t help here. In fact, it even hurts. With the writing of a unit test for that useless class it cements it into the system. You wouldn&amp;rsquo;t throw that well-tested class away, now would you?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The class might make assumptions about the context that aren&amp;rsquo;t valid. A common thing to &amp;ldquo;demo&amp;rdquo; TDD itself is to write a function that generates the Fibonacci sequence in test-driven style. Obviously, it&amp;rsquo;s a demo of a concept and not part of a mathematical library but even so - most implementations will recurse into a stack overflow, and generally be slow as molasses. Because they&amp;rsquo;re simplistic, and that&amp;rsquo;s fine. Except when it&amp;rsquo;s not.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;That part, the &lt;em&gt;wrong approach, try again&lt;/em&gt; part of software development, is completely ignored by TDD. Sometimes you&amp;rsquo;d even hear that wrong approaches just don&amp;rsquo;t happen with TDD (which is so obviously ignorant it hurts). Other times, TDD proponents will lean on the good code coverage their approach generates. This supposedly makes rewriting the code easy and - most of all - save.&lt;/p&gt;
&lt;p&gt;So that&amp;rsquo;s the next topic: code coverage.&lt;/p&gt;
&lt;p&gt;There are a couple of ways to measure code coverage. And there&amp;rsquo;s the nice buzz word of &amp;ldquo;100% code coverage&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Yes, there &lt;em&gt;is&lt;/em&gt; such a thing as 100% coverage. For example, you can exhaustively test the addition of two 32 bit integers by writing 18446744073709551616 tests. But since running those tests would take a few years, I think we can conclude that exhaustive testing isn&amp;rsquo;t practical. &lt;strong&gt;With exhaustive testing also dies the idea of &amp;ldquo;100% code coverage&amp;rdquo;&lt;/strong&gt;. What do people even measure to come to the incredibly stupid conclusion that they are testing 100% of anything?&lt;/p&gt;
&lt;p&gt;In the PHP world, when people say &amp;ldquo;100%&amp;rdquo;, they mean &amp;ldquo;100% lines of code&amp;rdquo; because that&amp;rsquo;s what the main PHP testing tool puts out. Other environments will have other conventions - slightly different stupidity of the same magnitude.&lt;/p&gt;
&lt;p&gt;Line-based, and token-based, coverage measurement is easily debunked by changing the &lt;em&gt;value&lt;/em&gt; of the things the tokens stand for. In other words: if the program is using variables, constants, or symbols of any kind, a lexical approach to coverage-measurement won&amp;rsquo;t tell you anything. Your tests &lt;em&gt;may&lt;/em&gt; cover the whole space of possible tests (unlikely, see integer example above), or they may just cover a tiny portion of it.&lt;/p&gt;
&lt;p&gt;Branch coverage is a stronger measurement, since that at least has a runtime portion to it. But what is a branch? Do you count every single jump-if-zero on the CPU level? Do you count fall-through cases in switch-case statements? Do you count vtables and dynamic dispatch systems? Obviously, &lt;em&gt;even if&lt;/em&gt; that is all factored-in: you still don&amp;rsquo;t know if you are really covering 100%. Many common sources of bugs - integer overflows, buffer overruns, off-by-one errors of all kinds - are still easily achieved with 100% branch coverage.&lt;/p&gt;
&lt;p&gt;And then there&amp;rsquo;s &amp;ldquo;100% of all functions or methods called&amp;rdquo; - well, you&amp;rsquo;re not even trying, are you?&lt;/p&gt;
&lt;p&gt;So that kind of &amp;ldquo;coverage&amp;rdquo; (and even &amp;ldquo;more coverage than before&amp;rdquo;) doesn&amp;rsquo;t tell you &lt;em&gt;shit&lt;/em&gt; about how save it is to refactor that code. It doesn&amp;rsquo;t tell you anything about &lt;em&gt;what&lt;/em&gt; is tested, how it&amp;rsquo;s tested, and whether or not that all makes sense. It doesn&amp;rsquo;t tell you if you&amp;rsquo;re going to be lucky and break your new code in exactly such a way that a test catches it. Increased &amp;ldquo;coverage&amp;rdquo; does not imply increased safety. Not at all.&lt;/p&gt;
&lt;p&gt;Aside: this has a social/cognitive dimension, too. If you believe that what you&amp;rsquo;re doing is save because of bogus measurements of test effectiveness, that can actually be more dangerous than not having any tests at all. If there are no tests then it&amp;rsquo;s clear that your brain is the thing that will have to make it work. So you have to &lt;em&gt;think&lt;/em&gt; about what you&amp;rsquo;re doing, and how it affects the system. If, however, you &lt;em&gt;believe&lt;/em&gt; that the tests catch you, you&amp;rsquo;re probably going to be a little more sloppy. It&amp;rsquo;s like a handrail that&amp;rsquo;s not bolted on properly. If people lean on it, that can easily be more dangerous than not having a handrail at all.&lt;/p&gt;
&lt;p&gt;But TDD proponents being ignorant is one thing. What &lt;em&gt;really&lt;/em&gt; bugs me about this is that the &amp;ldquo;100% coverage&amp;rdquo; story is what programming is all about.&lt;/p&gt;
&lt;p&gt;This is the fundamental &lt;em&gt;thing&lt;/em&gt; about programming: there are umpteen-million-billion cases, and &lt;em&gt;we just cannot try them all&lt;/em&gt;. We do not, and we &lt;em&gt;can not&lt;/em&gt; know if that program will even halt.&lt;/p&gt;
&lt;p&gt;And coming into that fundamental problem of computer programming, coming to people who &lt;em&gt;all&lt;/em&gt; work around it in various clever ways, with a &amp;ldquo;solution&amp;rdquo; that basically says &amp;ldquo;I know, we&amp;rsquo;ll just ignore it&amp;rdquo; - that, my friend, that makes me angry.&lt;/p&gt;
&lt;hr&gt;&lt;p&gt;What we ought to do instead is trying to make sure our programs are correct by making it easy to reason about them. Patiently write our regression tests for every reported bug. Write acceptance tests, automated integration tests, that make sure that at least the common paths through the whole thing still work.&lt;/p&gt;
&lt;p&gt;And not claim that this is the silver bullet that kills all bugs.&lt;/p&gt;
&lt;p&gt;Dijkstra:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Testing shows the presence, not the absence of bugs.&lt;/p&gt;
&lt;/blockquote&gt;</description><link>https://dev.imagineeasy.com/post/79356891740</link><guid>https://dev.imagineeasy.com/post/79356891740</guid><pubDate>Wed, 12 Mar 2014 09:17:00 -0400</pubDate><category>TDD</category><category>rant</category><dc:creator>badlynamedcode</dc:creator></item><item><title>The Angel of Refactoring</title><description>&lt;p&gt;&lt;img src="http://www.gravatar.com/avatar/0164510d5bb40163d77e0a761bda9ab8.png" alt="Yitzchak"/&gt;
by &lt;a href="http://twitter.com/yitznewton" target="_blank"&gt;Yitzchak Schaffer (@yitznewton)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is one of the nicest feelings in coding. You&amp;rsquo;ve been working a couple of
hours on some legacy code, with a thorny refactoring of stuff that&amp;rsquo;s used in
a couple of places. After a morning buried in the code that deals with one of the implementations, you have a nicely
reworked version, and you&amp;rsquo;re at a few hundred lines of delta.&lt;/p&gt;

&lt;p&gt;You realize you now need to implement the new solution in the other place where this problem is addressed. That code, you remember, is a bunch of hacked-together smelly rubbish. You grumble, wondering how much more work this is going to take.&lt;/p&gt;

&lt;p&gt;But the Angel of Refactoring is waiting for you in the other spot. You look at the code, and realize that the new version has this case covered without
contorsions, and this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$presenter = $this-&amp;gt;getPresenter();
$presenter-&amp;gt;setProjects(array($project-&amp;gt;toArray()));
$collection = json_decode(json_encode($presenter-&amp;gt;handle()), true);
$this-&amp;gt;result = $this-&amp;gt;apiLinkTransformer-&amp;gt;transform($collection[0]);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;hellip; becomes this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$this-&amp;gt;result = $this-&amp;gt;getProjectDecorator()-&amp;gt;decorateProject($project);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And all you can say is: XD&lt;/p&gt;

&lt;p&gt;Thank you, Angel of Refactoring!&lt;/p&gt;</description><link>https://dev.imagineeasy.com/post/78658189850</link><guid>https://dev.imagineeasy.com/post/78658189850</guid><pubDate>Wed, 05 Mar 2014 11:54:00 -0500</pubDate><category>refactoring</category><dc:creator>yitznewton-blog</dc:creator></item></channel></rss>
