<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">

<channel>
   <title>Brian Nesbitt's  Blog</title>
   <link>http://nesbot.com</link>
   <description>Developer who is always consuming knowledge. Startup enthusiast who doesn't enjoy being a drop in a bucket. Dividend stock investor. Lucky husband and father.</description>
   <language>en-us</language>
   <managingEditor>brian@nesbot.com (Brian Nesbitt)</managingEditor>
   <image>
      <url>http://nesbot.com/img/logo.gif</url>
      <title>Brian Nesbitt's  Blog</title>
      <link>http://nesbot.com</link>
   </image>
   <atom:link href="http://nesbot.com/rss" rel="self" type="application/rss+xml" />

      <item>
      <title>A carpenter's house is always the last to get the attention it deserves</title>
      <link>http://nesbot.com/2011/9/7/carpenters-house-last-to-get-attention</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Wed, 07 Sep 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/9/7/carpenters-house-last-to-get-attention</guid>
      <description><![CDATA[<p>My history in less than 3 tweets.</p>

<p><i>I graduated from computer systems engineering and for 2 years worked at <a href="http://www.lockheedmartin.com/canada/">Lockheed Martin Canada</a> as an embedded C++ developer. Left in late '99 and co-founded <a href="http://www.fuelindustries.com">Fuel Industries</a>. Fast forward about 10 years, 100+ employees, a wife, 2 moves and <strike>1</strike> 2 son's, I made the difficult decision to move on from the typical non-stop roller-coaster ride of a startup.</i></p>

<p>At the time, leaving Lockheed was a big decision, but I don't regret it for a second as Fuel provided invaluable continuous learning that will last with me forever.  It provided me the very <a href="http://www.paulgraham.com/foundersatwork.html">unique experience of building a company</a> from a few employees to working with literally hundreds of great clients, projects and people over that 10 year span.</p>

<p>Awhile ago I read an interesting article that talks about <a href="http://www.smashingmagazine.com/2010/12/28/how-to-maintain-your-personal-brand-as-a-corporate-employee/">your personal profile vs company profile</a>.  It was an interesting read for me since I have been on both sides of the fence.  During that (what seems like a blur looking back) phase my time was usually more valuably spent in the business as there was never any shortage of todo's.  There was just not enough of me left to build and contribute to any form of a personal site - everything was put into the business.  My wife and I <strike>are expecting a 2nd son in March</strike> had our 2nd son this past March and after a few months in hospital with him (a very long story for another time), we are all back home safely.  I figure now is as good a time as any.  I decided to create this site to write, good or bad, to whomever wants to listen (anyone out there??).  I expect there will be a variety of topics including programming, startups, dividend investing, hockey and whatever else floats my boat (did I really just type that??) in the future.</p>

<p>By no means do I think I am a good writer (or fast reader) as I have always been better with numbers than words (thats why I married an english major! :-).  Most of my past writing has been either for proposals or some kind of technical documenation - a topic for another day.  I anticipate this site to be a great channel to practice and maybe receive a little, hopefully constructive, criticism along the way.  Just like most skills, writing requires you to practice to get better and this is a step in the right direction for me.  If I manage to help anyone else along the way then thats all right with me as well.</p>
]]></description>
   </item>
      <item>
      <title>Adding initial Windows support for the Play! Framework 2.0 preview</title>
      <link>http://nesbot.com/2011/9/8/windows-support-for-play-framework-2-preview</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Thu, 08 Sep 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/9/8/windows-support-for-play-framework-2-preview</guid>
      <description><![CDATA[
<p>As many of you saw the Play framework team released their plans on the upcoming <a href="http://www.playframework.org/2.0">2.0 release</a>.  I tried it out on a remote linux machine and it worked as expected.  My desktop runs Windows though and the current preview package doesn't work on Windows yet, but its a pretty simple task to get it up and running for now until official support is added.</p>

<p>Download the <a href="http://download.playframework.org/releases/play-2.0-preview.zip">preview package</a> and unzip to <code>c:\</code> (or a directory you prefer, but the rest of the post will assume <code>c:\</code>) so you now have a <code>c:\play-2.0</code> directory.</p>
<p>Download <a href="https://github.com/briannesbitt/Play20/blob/windows-support/play.bat">play.bat</a> and put it in <code>c:\play-2.0</code></p>
<p>Download <a href="https://github.com/briannesbitt/Play20/blob/windows-support/framework/build.bat">build.bat</a> and put it in <code>c:\play-2.0\framework</code></p>

<p>In the following commands I'll use the full path to the <code>play.bat</code> file as some of you will probably have a previous version of <code>play.bat</code> in your PATH and we want to ensure we are running the correct version.</p>

<p>Now lets go ahead and create a new project.</p>

<pre><code class="bash">
c:
cd \
mkdir newproject
cd newproject
c:\play-2.0\play.bat new
</code></pre>

<p>The framework will now ask for an application name.  You can specify something else or just hit ENTER to accept the default <code>newproject</code>.  Once accepted a full Play! 2.0 project will be created in the current directory.</p>

<p>Now lets go ahead and run the new project via the new Play! console.</p>

<pre><code class="bash">
c:\play-2.0\play.bat    #shows some [info] logs and then runs the console
</code></pre>

<p>Once the console is running and waiting for your command, type <code>run</code>.  Now open a browser to <code>http://127.0.0.1:9000</code> and say Hello!</p>

<p>You can also launch the console and auto run with <code>c:\play-2.0\play.bat run</code> as usual.  Hitting CTRL-D will just drop you back to the console.</p>

<p>I forked the project on github and had recompiled the framework to test the .bat files and I got some weird dependency issues.  I fixed it by deleting my <code>~/.iv2</code> contents which for me was located at <code>c:\Users\brian\.ivy2</code>.  This tip was taken from the <code>Play20/README.textile</code> repo so thanks to guillaume for that simple but useful comment, otherwise this wouldn't have gotten done.</p>

<p>Looks like this means I now have to start looking into <a href="http://www.scala-lang.org/">Scala</a> some more.</p>

<p>Congrats to the Play! team and also to the community as we get to reap the benefits of their hard work!</p>

   <p class="quote"><b>UPDATE:</b> to fix the ANSI control characters in the play output see <a href="http://nesbot.com/2011/9/9/ansi-colour-support-for-play-framework-2-preview">ANSI colour support in Windows for the Play! Framework 2.0 preview</a></p>
]]></description>
   </item>
      <item>
      <title>ANSI colour support in Windows for the Play! Framework 2.0 preview</title>
      <link>http://nesbot.com/2011/9/9/ansi-colour-support-for-play-framework-2-preview</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Fri, 09 Sep 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/9/9/ansi-colour-support-for-play-framework-2-preview</guid>
      <description><![CDATA[
<p class="quote">This is a follow up to <a href="http://nesbot.com/2011/9/8/windows-support-for-play-framework-2-preview">Adding initial Windows support for the Play! Framework 2.0 preview</a>... you may want to go and read that first.</p>
<p>As pointed out today the Windows version outputs various ANSI color codes rather than changing the color of the text.  There aren't many so they don't really get in the way, we just don't get color.</p>

<p>For example when creating a new project in a directory that contains files you should get an error message in red:</p>
<p><code style="color:red">The directory is not empty, cannot create a new application here.</code></p>

<p>Well on windows at the moment you get:</p>
<p><code>[31mThe directory is not empty, cannot create a new application here.[0m</code></p>

<p>The fix comes via <a href="http://adoxa.110mb.com/ansicon/index.html">Ansicon</a>, a clever C app that "provides ANSI escape sequence recognition for Windows console programs (both 32- (x86) and 64-bit (x64)). It is basically the Windows equivalent of ANSI.SYS".</p>

<p>Here we go with the instructions. First, you are going to have to re-download the <code>play.bat</code> file as I have pushed an update to integrate Ansicon. I augmented the batch file with a registry check to see which OS bitness is installed which is needed later.</p>

<p>Download <a href="https://github.com/briannesbitt/Play20/blob/windows-support/play.bat">play.bat</a> and put it in <code>c:\play-2.0</code></p>

<p>Now for Ansicon.  They provide seperate binaries for 32 and 64 bit.</p>

<p>Download <a href="http://nesbot.com/downloads/playAnsicon.zip">playAnsicon.zip</a> and unzip it to <code>c:\play-2.0</code>.  This should give you the following directories <code>c:\play-2.0\ansicon\x86</code> and <code>c:\play-2.0\ansicon\x64</code> each with some dll's and their respective <code>ansicon.exe</code>.</p>

<p>That should be it.  Now when you run the <code>play.bat</code> script you should see some glorious <span style="color:blue">c</span><span style="color:red">o</span><span style="color:green">l</span><span style="color:red">o</span><span style="color:blue">u</span><span style="color:green">r</span>!</p>

<p>Someone on the playframework group mentioned that the same issue occurs with Jenkins.  This fix should be able to work with it as well.  Basically I found you can ansicon 2 ways.  If you run <code>ansicon.exe -p</code> from the cmd prompt, then any commands after that should interpret ANSI colour.  I use <a href="http://sourceforge.net/projects/console/">console2</a> as a Windows console replacement, mostly for the tabs, and I found this initial method didn't work because of the way cmd gets wrapped by the parent application.  The other way you can run ansicon is by piping output to it and have it echo it while interpreting ANSI escape commands along the way, <code>myFunCommandThatDoesSomething | ansicon.exe -t</code>.</p>

<p>I hope at some point this can get pulled into the master trunk for us Windows folk.</p>]]></description>
   </item>
      <item>
      <title>Tricks for using the cobertura module with the Play Framework</title>
      <link>http://nesbot.com/2011/9/20/cobertura-module-tricks-with-the-play-framework</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Tue, 20 Sep 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/9/20/cobertura-module-tricks-with-the-play-framework</guid>
      <description><![CDATA[<p><i><a href="http://cobertura.sourceforge.net/">Cobertura</a> is a free Java tool that calculates the percentage of code accessed by tests. It can be used to identify which parts of your Java program are lacking test coverage. It is based on jcoverage.</i></p>

<p>I had a few frustrating (actually rather simple, but frustrating none the less) moments when first starting to use the cobertura module.  I have documented them here to try and help others quickly bypass the things I found.  Admittedly they are rather small issues, but apparently tricky enough as I have seen more than a few threads on the google group about them.  My current working configuration is at the bottom of this post if you want to bypass the why (and miss all the fun!!).</p>

<h2>Default configuration issues</h2>

<p>I know it mentions how to setup the configuration in the docs, but the default <code>application.conf</code> file created by <code>play new</code> adds some confusion.  It sets up the module line for cobertura but does not include the rest of the required config.  Not to mention it references a default cobertura directory, but whether you <code>play install cobertura</code> or use the <code>dependencies.yml</code> file, it gets put in a cobertura-2.2 (ie. latest version) so you have to update the referenced directory anyway.  But the real issue is if you just enable this line you <b>won't get proper code coverage results</b> - at least not consistently.</p>

<p>On the <a href="http://www.playframework.org/modules/cobertura-2.2/home">module documentation page</a> it shows the following sample configuration usage.</p>

<pre><code class="bash">
%test.module.cobertura=&#36;{play.path}/modules/cobertura
%test.play.tmp=none
%test.cobertura.silent=false
</code></pre>

<p>Line 1 should actually reference the module in a directory stamped with the version.  This means that the line in your conf file should be (based on the version you have installed):</p>

<pre><code class="bash">
%test.module.cobertura=&#36;{play.path}/modules/cobertura-2.2
</code></pre>

<h2>Setting the tmp folder to none</h2>

<p>Now, you can run with just the first line, but you may need to run <code>play clean</code> first otherwise you might get coverage reports of 0% everywhere if your class files have already been compiled but not enhanced.  Setting the play tmp to none ensures your class files will get regenerated and enhanced every time and will prevent the 0% coverage.</p>

<h2>Silent mode... should it be True or False?</h2>

<p>I expected this configuration setting to work exactly the opposite as it does.  Usually if I want something to output nothing, like a shell command or script, I look for a "-q" (quiet) or "-qq" (very quiet/silent) option and turn it on to suppress output.  The documentation usage sample has this set to false, which initially makes sense since I don't want it to be silent, I <b>want</b> it to generate the coverage report.  This is <b>not</b> how the configuration option works.  Lets look at the code to see what is happening.</p>

<pre><code class="java">
String silentString = Play.configuration.getProperty("cobertura.silent", DEFAULT_SILENT_MODE);

boolean silent = Boolean.parseBoolean(silentString);

if(silent){
    Logger.trace("Cobertura plugin: Add Cobertura Shutdown Hook");
    // register a shutdown hook so that the Cobertura coverage report
    // will be generated on shutdown
    Runtime.getRuntime().addShutdownHook(new CoberturaPluginShutdownThread());
}else{
    Logger.debug("Cobertura plugin: Not add Cobertura Shutdown Hook. Work with explicit call");
}
</code></pre>

<p>You can easily see this code requires the <code>cobertura.silent</code> configuration set to <code>true</code> to install the shutdown hook which will generate the report at shutdown.  As I said, the opposite to what I expect.  As it turns out, the <code>DEFAULT_SILENT_MODE</code> is set to true so you can remove this configuration setting altogether and it will setup the shutdown hook by default.  If you do have it set to false, you have to trigger the report generation manually.  When your application is running in test mode you can browse to <code>http://127.0.0.1:9000/@cobertura</code> to view a generated report, generate a new one or clear the current one.</p>

<p>Since you can always use the generate report url to trigger the event regardless of the silent setting, I would suggest to rename this configuration to <code>cobertura.installShutdownHook</code>.  I leave the exercise as to what you expect to happen with true/false settings to you :-)</p>

<h2>Ignoring classes in coverage report</h2>

<p>According to the same documentation page you can apply an ignore list via comma delimited class names or comma delimited regex's.</p>

<pre><code class="bash">
%test.cobertura.ignore=DocViewerPlugin,Cobertura,CheatSheetHelper,PlayDocumentation
%test.cobertura.ignore.regex=*Plugin
</code></pre>

<p>When I first tried this it <b>didn't work</b> for me.  I still got the classes I wished to ignore in the code coverage report.  As it seems to be a regular occurrence, I opened up the src.</p>

<p>Opening the CoberturaPlugin class <code>playframework\modules\cobertura-2.2\src\play\modules\cobertura\CoberturaPlugin.java</code> you want to look at the <code>public void enhance(ApplicationClass applicationClass)</code> method.  This is the method that gets called by the framework to enhance the compiled bytecode and inject the necessary cobertura instrumentation for tracking code coverage.  The code in that method we want to check is:</p>

<pre><code class="java">
// - don't instrument specific classes define in cobertura.ignore
String ignoreString = Play.configuration.getProperty("cobertura.ignore");

if(ignoreString != null){
   String[] ignoreTab = ignoreString.split(",");
   for (String ignore : ignoreTab) {
      if(applicationClass.name.equals(ignore)){
         return;
      }
   }
}
</code></pre>

<p>After that the following code traces the class that passed the ignore list and is about to be instrumented:</p>

<pre><code class="java">
Logger.trace("Cobertura plugin: Instrumenting class %s", applicationClass.name);
</code></pre>

<p>If we see this trace it means the class didn't get ignored and it would get included in the coverage report. So if we set the conf file to log at the trace level "application.log=TRACE" and run the application in test mode <code>play test</code> we can watch the traces to see what is going on.</p>

<pre><code class="java">
16:29:08,805 TRACE ~ Cobertura plugin: Instrumenting class helpers.CheatSheetHelper$1
...
16:29:08,956 TRACE ~ Cobertura plugin: Instrumenting class helpers.CheatSheetHelper
...
16:29:09,259 TRACE ~ Cobertura plugin: Instrumenting class controllers.Cobertura
...
</code></pre>

<p>You can quickly see that the <code>applicationClass.name</code> is the full name with package and this is why the class is not getting ignored. The provided sample doesn't use the full name.  So the easy fix is to specify the ignore list like so:</p>

<pre><code class="bash">
%test.cobertura.ignore=DocViewerPlugin,controllers.Cobertura,helpers.CheatSheetHelper,helpers.CheatSheetHelper$1,helpers.CheatSheetHelper$2,helpers.CheatSheetHelper$3,controllers.PlayDocumentation
</code></pre>

<p>Now when you run the tests and regenerate the code coverage report you will only see your classes.</p>

<h2>Ignore classes in coverage reports using regular expressions</h2>

<p>On Aug 30, 2011 the module was updated to version 2.2 and included a feature allowing you to ignore classes using a regular expression.  This will help us simplify our ignore statement.  The new code uses the same <code>applicationClass.name</code> property when matching against the regex so it still includes the package name.  The new minimized ignore configuration looks like this:</p>

<pre><code class="bash">
%test.cobertura.ignore=DocViewerPlugin,controllers.PlayDocumentation
%test.cobertura.ignore.regex=*Cobertura*,helpers.CheatSheetHelper*
</code></pre>

<p>Of course there are a few different ways to write those, but I went with what you see and haven't seen any unwanted classes being shown.  You'll also want to add any other plugins that you use that would muddy your coverage report.</p>
<h2>Automatically ignoring your test classes</h2>

<p>The author of the plugin has added code to automatically ignore some default class names.  First, if you name your test classes ending with <code>Test</code> then it will get ignored.  The have also auto ignored the play TestRunner.  However, I am not so sure this is necessary since we have the ignore feature.  Its probably best in the configuration rather than hard coded.</p>

<pre><code class="java">
// check if we should instrument this class or not
// - don't instrument Test classes (**/*Test.java)
// - don't instrument the TestRunner class from the test-runner module
if (applicationClass.name.endsWith("Test") || applicationClass.name.equals("controllers.TestRunner")) {
    return;
}
</code></pre>

<h2>My current working configuration</h2>

<p>I have included my current configuration here. It is only 5 lines, but hopefully it will be smoother for the next person.</p>

<pre><code class="bash">
%test.module.cobertura=&#36;{play.path}/modules/cobertura-2.2
%test.play.tmp=none
%test.cobertura.silent=true
%test.cobertura.ignore=DocViewerPlugin,controllers.PlayDocumentation
%test.cobertura.ignore.regex=*Cobertura*,helpers.CheatSheetHelper*
</code></pre>

<p>I will just finish this by saying that this is <b>not meant</b> to be a dig on the author of the module in any way.  The author's github profile shows that he works from Paris, France and maybe some of the confusion is from english not being their first language.  From the looks of the comments and module documentation its possible, but I can safely say his english is better than my french :-)  Maybe next time I will just fork his repo and submit a pull request with some of these changes and contribute, like they did, and save myself from writing this much again.  Either way I'll be continuing to use the module.</p>]]></description>
   </item>
      <item>
      <title>Why and How I will switch to a stand-up desk</title>
      <link>http://nesbot.com/2011/9/22/why-and-how-i-will-switch-to-a-stand-up-desk</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Thu, 22 Sep 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/9/22/why-and-how-i-will-switch-to-a-stand-up-desk</guid>
      <description><![CDATA[
<p>With all the hype in the past few years about our unnatural sedimentary lives killing us (if you missed it see the links at the end of this post) I decided that I am going to join the ranks of the standing.  My position, pun intended, is that too much of a good thing quickly becomes a bad thing.</p>

<h2>Too much sitting is bad. Too much standing is bad.</h2>

<p>I really think the best position is one that is constantly dynamic.  Of couse you can't be changing so much that it affects your work or concentration, but I think completely adjusting your position every 15-30 minutes is fine.  Sometimes if you get in the zone and you go for longer its ok because you'll go back to changing more frequently shortly after, as long as it doesn't happen all the time.</p>

<p>I think you can also make micro adjustments subconciously, without breaking your train of thought, almost constantly if not at least every 15-30 seconds.  For example if you are sitting, you can fidgit your legs, arms etc., just adjust your torso and try to always keep moving a little.  I think one of the big benefits of standing is that it should make this much easier.  Think of yourself the last time you stood for your national anthem, at a meeting or even in line at a store.  I bet you constantly moved without even really knowing it.  Most people aren't completely still while standing even if its just for a few minutes.  When you are standing all day there is so much more movement you can do to stay dynamic compared to sitting and I think this is where standing will really shine.</p>

<h2>Current Desk</h2>

<p>My current desk will accomodate a standing position quite easily. I have the original jerker from Ikea and I will be able to raise it to the perfect height for me.  I'll probably have to remove the top shelf, which is not a big deal.  Here is a picture of my current desk and setup:</p>

<p><a href="http://twitpic.com/683ppa"><img src="http://nesbot.com/img/posts/desk.jpg" /></a></p>

<p>In case you are wondering I use a Microsoft natural ergonomic 4000 keyboard with a Logitech MX1100 mouse.  The 3 monitors I have are setup as a reverse barbell, older viewsonic's @ 1680x1050 on the outside and a portrait samsung @ 1152x2048 in the middle.  I only recently added a third monitor at home, just about a month ago, and at the same time I picked up 3 monitor arms to hold the monitors.  I have never used monitor arms before, as until now I have always just made wooden stands for whatever desk I was at (work or home).  If I knew sooner, I would have made this purchase a long time ago.  I am definitely of the opinion that more of your money should go towards your desk, chair, monitors, keyboard and mouse than your actual computer hardware components - a topic for another day.  The monitor arms purchase was easily one of my best, the flexibility in position they provide is great and will be particularly handy when raising my desk.</p>

<h2>GelPro Plush Anti-fatigue mat</h2>

<p>I was all ready to go when I thought what am I going to stand on.  My flooring is a hard laminate so I am going to need something soft and absorbing to support me and should I wear running shoes? Socks? Bare feet? So after more online searching I realized there was a whole market for anti-fatigue mats.  Commercially they are usually large and expensive and target stand up jobs (think assembly line, factories, etc) but for residential they target your kitchen where we tend to spend a lot of time standing preparing meals and cleaning.  There are a lot of $20 - $40 mats on Amazon that claim to be anti-fatigue mats.  I am not sure they are worthy of the name but following my own advice on where money should be spent and knowing this mat will effectively be replacing my chair I didn't think they would be adequate.  It seems the best of the best anti-fatigue mats are made from gel rather than foam.  I found <a href="http://gelpro.com">gelpro.com</a>, they sell custom made GelPro and GelPro Plush mats made from gel and they provided enough evidence for me that they would be better.  On September 9 I ordered a 20x36 GelPro Plush Woven Teak mat.  I also just found out that they make them when ordered so it does really take a couple of weeks to arrive, most of which is manufacturing time.  At the time of this writing mine is in Windsor, ON so I expect to recieve it in the next few business days.</p>

<h2>Keyboard positioning</h2>

<p>I am 6' 3" tall.  My desk will be set at 39" high.  This gives me the option to put a reverse tilt (away from you) of about 45 degrees on the keyboard and have my arms and wrists in a perfect position.  When you do the reverse tilt you generally have your keyboard height about 2" lower than you would if you just used a flat keyboard angle.</p>

<p>The beauty part about this height setting is I can easily prop the whole keyboard up those same 2" and set the reverse tilt to the normal 7 degrees using the provided support with the Microsoft natural keyboard 4000.  This gives me 2 really good keyboard positions and I think I will frequently switch between them throughout the day.</p>

<h2>Monitor positioning</h2>

<p>Not much to say here I didn't say before.  Get monitor arms.  Short of that, whether sitting or standing make sure they are positioned correctly.  Get monitor arms.  From what I understand you want your eyes to be aligned with the upper half of your monitor screen.  Get monitor arms.</p>

<h2>Other suggestions I have read</h2>

<p>Some other suggestions I have read that facilitate constant dynamic movement include using a 6" block under one leg at a time and shift legs every so often.  I also read that you can stand on a balance board to really work your legs and core rather than standing alone.  I suspect this is something that you need to work up to before you attempt a longer session.</p>

<h2>Final thoughts and some light reading</h2>

<p>I don't really have many expectations either way.  I have read that for the majority who try it, they never go back.  Apparently its pretty rough for the first 3 days, dramatically improves by the fourth day and by the end of the first week you don't realize you are standing any more.  The other benefit that was pretty much unanimous was that it greatly reduced, if not completely removed, the typical mid afternoon drowsiness.  A general feeling of more energy seemed to also be quite common - who doesn't need that?!?</p>

<p>I'll have more to report in the next few weeks as my mat arrives and I re-configure the desk.  Until then I'll leave you with some light reading.</p>

<p>
   <a href="http://www.medicalbillingandcoding.org/sitting-kills/">http://www.medicalbillingandcoding.org/sitting-kills/</a><br/>
   <a href="http://online.wsj.com/article/SB10001424053111904199404576541011003270644.html">http://online.wsj.com/article/SB10001424053111904199404576541011003270644.html</a><br/>
   <a href="http://en.wikipedia.org/wiki/Standing_desk">http://en.wikipedia.org/wiki/Standing_desk</a><br/>
   <a href="http://opinionator.blogs.nytimes.com/2010/02/23/stand-up-while-you-read-this/">http://opinionator.blogs.nytimes.com/2010/02/23/stand-up-while-you-read-this/</a><br/>

   <a href="http://www.nytimes.com/2010/04/22/technology/personaltech/22basics.html">
   http://www.nytimes.com/2010/04/22/technology/personaltech/22basics.html</a><br/>

   <a href="http://smarterware.org/7102/how-and-why-i-switched-to-a-standing-desk">http://smarterware.org/7102/how-and-why-i-switched-to-a-standing-desk</a><br/>

   TheCareerDiva takes her blood pressure, pulse and weight and reports after 2 weeks:
   <a href="http://www.youtube.com/user/TheCareerDiva#p/u/2/3n4tE_X_loU">Video 1</a>
   <a href="http://www.youtube.com/user/TheCareerDiva#p/a/u/1/NbyNP_21fbs">Video 2</a>
   <a href="http://www.youtube.com/user/TheCareerDiva#p/a/u/0/kHGOcurwaq0">Video 3</a><br/>

   <a href="http://imperialwicket.com/standing-in-the-cube">http://imperialwicket.com/standing-in-the-cube</a><br/>
   <a href="http://www.nytimes.com/2011/04/17/magazine/mag-17sitting-t.html?_r=1">http://www.nytimes.com/2011/04/17/magazine/mag-17sitting-t.html?_r=1</a><br/>
   <a href="http://www.marksdailyapple.com/standing-at-work/">http://www.marksdailyapple.com/standing-at-work/</a><br/>
</p>

   <p class="quote">Read the follow up to hear day 1 results... <a href="http://nesbot.com/2011/10/3/day-1-of-my-move-to-a-stand-up-desk">Day 1 of my move to a stand-up desk</a></p>
]]></description>
   </item>
      <item>
      <title>Day 1 of my move to a stand-up desk</title>
      <link>http://nesbot.com/2011/10/3/day-1-of-my-move-to-a-stand-up-desk</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Mon, 03 Oct 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/10/3/day-1-of-my-move-to-a-stand-up-desk</guid>
      <description><![CDATA[
<p class="quote">This is a follow up to <a href="http://nesbot.com/2011/9/22/why-and-how-i-will-switch-to-a-stand-up-desk">Why and How I will switch to a stand-up desk</a>... you may want to go and read that first.</p>
<p>I completed day 1 of using my stand-up desk.  I was prepared for a rough start as most others suggest the first 3 days are the worst.  It is 11:30 PM here and as I stay up to wait to feed our 6 month old in another 30 minutes, my legs, feet and I feel fine.  I don't know what shape etc the others were in, but I feel fine.  I even had our 2 young kids myself tonight so even when I wasn't "working" standing I was definitely on the move !</p>

<p>I really tried to keep moving during the day while standing.  I think it was quite successful actually for a first day, constantly shifting.  I think it did keep me more alert and I don't ever really remember having any moments of tiredness as can sometimes happen when sitting.</p>

<h2>Desk Setup</h2>

<p>Here is a picture of the desk setup.  As I mentioned before I was able to just raise my current desk, the original ikea jerker.</p>

<p><a href="http://twitpic.com/6ut258"><img src="http://nesbot.com/img/posts/standupdesk.jpg" /></a></p>

<p>I am very happy with the height, position and general configuration of the desk, keyboard and monitors.  I now have the desk set at 44" high, for reference I am 6' 3" tall.  The mat I am standing on (I'll talk about that more in a moment) does raise you up a good 3/4" so over the weekend I actually had adjusted the desk height twice, slightly increasing each time until I got it just right.  I am able to adjust it in 1.25" increments.  Not to mention, I actually gained a 2nd shelf that I had removed awhile ago.  After using the desk for 1 day I am starting to realize that the mouse is a little low.  My keyboard is naturally raised a litte since I have the reverse slope attachement on.  I am going to adjust the mouse a little higher, approx 1.5", which should be relatively easy to do, and probably add a small reverse slope to it as well so its just right.  Raising the desk higher at this point for the mouse alone would put the keyboard too high so its just a minor adjustment.</p>

<h2>General Environment : Temperature & Humidity</h2>

<p>The other 2 things (partly because my office is in a basement and I live in Canada) I wanted to track about the enviroment I spend a lot of time in is the temperature and relative humidity.  According to the <a href="http://www.ccohs.ca/oshanswers/phys_agents/thermal_comfort.html" target="_blank">Canadian Centre for Occupational Health and Safety</a> the temperature for an office setting should be in the range of 21-23&deg;C.  Its actually based on the relative humidity and season as well, but generally I would say that sounds about right.  The relative humidity should be between 40-60%.  Personally my body has always run hot (no seriously!) so I would always tend to prefer the cooler side of that range.  Now that I am standing, which means I am working harder than when sitting, I prefer the temperature to be even cooler by a couple of degrees, say 19-20&deg;C.  With a window right beside me and winter coming I don't think having it too hot is going to be the issue, and I really wanted to ensure it didn't get too cold when its -25&deg;C outside. There are simple ways you can monitor the humidity (moisture on the windows = too high, static shocks when walking on carpet = too low) but I decided to get a more accurate measurement.  I purchased a "2 in 1 LCD Digital Indoor Thermometer W/ Hygrometer".  It only cost $5.56 shipped to my door.  If you zoom in on the desk picture you can see it just to the left of the keyboard and when I took the picture it was reading 22.1&deg;C and 53% relative humidity.  Just about right, a little warmer than ideal for me, but my shorts and t-shirt compensate nicely even when it only hit a high of about 12&deg;C today.</p>

<h2>Gelpro mat</h2>

<p><a href="http://www.gelpro.com/" target="_blank">http://www.gelpro.com/</a></p>

<p>I am standing on a 20x36 GelPro Plush Woven Teak mat.  It feels like someone took a cloud from the sky and put it under my feet!  I don't think I would be feeling as good as I do without the mat.  I have been standing on it all day with just bare feet and its been a difference maker.  I would highly suggest getting an anti-fatigue mat if you are going to attempt this.</p>

<p>A short customer service story as well for you.</p>

<p>If you read the FAQ on the gelpro.com site they mention that, when shipping to Canada, you will recieve a COD charge from UPS for the brokerage fee.  They also mention the following:</p>

<p class="quote">After paying the UPS COD charge simply fax Let's Gel a copy of the invoice and we would be happy to reimburse you for the UPS Brokerage fee. Please note: Customer is responsible for all local fees and taxes that are included in this COD charge.</p>

<p>Lets just say I wasn't banking on that happening for weeks, if at all.  Regardless, today I emailed in a scanned copy of my UPS brokerage fees, which for the record were only $15.80 but now it was more for the principal :-).  After clicking send to the "customerservice" address it really felt like I might have as well just piped it to /dev/null.  To my surprise about 2 hours later I received 2 emails in response.  The first was a canned response from a general "customerservice" email indicating my credit card had been refunded for $13.52 (the brokerage fee part of the expense).  Seconds later I got a 2nd email that was a custom response from a real human with a real name and direct phone number !  I was pleasantly surprised to get a such a speedy response, none the less from a real human.</p>

<h2>The stand-up desk is here to stay</h2>

<p>I think I have been pretty clear about my feelings so far of my stand-up desk experience.  The first day has been really enjoyable and a noticeable improvement overall.  I shall see what the next few days and weeks are like, but as far as I can tell my stand-up desk isn't going to walk away anytime soon.</p>]]></description>
   </item>
      <item>
      <title>How much code do you read?</title>
      <link>http://nesbot.com/2011/10/11/how-much-code-do-you-read</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Tue, 11 Oct 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/10/11/how-much-code-do-you-read</guid>
      <description><![CDATA[<p>Do you make it a point each day to read code?  Maybe it's during a peer review.  Maybe it's the linux kernel.  Maybe it's a search on github for your favourite topic.  Maybe the latest open source project released from google/facebook/twitter.  If you don't you should start...<b>today</b>!  I also think it goes beyond just source code.  Understanding different deployment systems or production environments can also provide a great learning experience.  Seeing how others write code, structure projects, create build systems and deploy can show you how to do things and maybe sometimes how not to do things.  Either can be equally as valuable.</p>

<p>You hear all the time how important it is for developers to consistently learn new languages.  I completely agree with this.  The other great thing about this is it forces you to read code, better yet new code.  Part of learning a new language is understanding why it was written and maybe some of the history of the language.  At some point though the only way to really "get it" is too read some code and then try it for yourself.  It can be a fun challenge to read some source of a new language and attempt to understand it.</p>

<p>During interviews at my old company we asked candidates about the worst/best code they had read lately.  The question was great at quickly filtering candidates.  We were never really that concerned with the worst or best part, but mostly with what code and how long ago, if at all.  With a high degree of accuracy, that one answer determined what level of developer they were.  The type of code and the detail involved during the potential conversation about it provided great insight.  If they hadn't read any code lately that has red flag written all over it.  Some better answers might be a few snippets on a blog, a particular project on github, the latest XYZ web framework, a compiler or kernel.</p>

<h2>How do I get started?</h2>

<p>The open source community is so vast that there are endless projects just waiting for your help.  You don't really need to go much further than <a href="http://github.com">github</a> to find a project you would be interested in and using github makes it very easy for you to get involved.  If you haven't used <a href="http://git-scm.com/">git</a> before (where have you been?!?) then you get to kill two birds with one stone, as they say.  Find a project and help fix a bug or submit a new feature, both will probably also involve some tests as well.  Doing this will force you to read other parts of the project which gets you to your end goal of reading more code.</p>

<p>What language are you going to learn next? What src have you read lately?</p>
]]></description>
   </item>
      <item>
      <title>Play framework sample application with JWebUnit and synchronous ajax</title>
      <link>http://nesbot.com/2011/10/16/play-framework-sample-app-JWebUnit-synchronous-ajax</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Sun, 16 Oct 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/10/16/play-framework-sample-app-JWebUnit-synchronous-ajax</guid>
      <description><![CDATA[<p>I had posted awhile ago on the Play framework google group that I had successfully started using <a href="http://jwebunit.sourceforge.net/">JWebUnit</a> for testing rather than the bundled <a href="http://seleniumhq.org/">selenium</a> suite.  At the time it was partly because the IDE autocomplete support for the test helper assert functions in JWebUnit were way more convenient compared to learning the selenium commands.  It also runs headless which makes CI easier, although Play 1.2 had already fixed that for selenium.  That post, after sitting dormant for awhile, recently had another user trying to get an ajax test working but was running into a timing issue.  Before you can assert the result of the ajax call you need to wait for the call to be completed.  By default, the ajax calls are performed asynchronously, so you don't have much choice but to call <code>Thread.sleep(X)</code> and hope you select an appropriate value for X.  This type of test is pretty fragile in my mind and in the future could possibly break and raise some false negatives about the underlying functionality.</p>

<p>Sure enough there was a solution already in place.  Registering an instance of <code>NicelyResynchronizingAjaxController</code> as the testing engine ajax controller makes the ajax call synchronous and removes the dependency on the <code>Thread.sleep(x)</code> call.  I reposted my findings and that user was then off to "write tons of code lines".</p>

<p>Shortly after another user requested if someone could share a sample application showing how to make it all work together as our posts had bits and pieces of code here and there. So I am about to share a sample and explain the tests a little.  I won't go into much detail about the rest of the sample (its pretty simple) but you can always ask questions if needed in the comments/email/twitter/google group and I'll try to help.</p>

<p>For reference, here is the <a href="https://groups.google.com/d/topic/play-framework/ut9DQ1numsA/discussion">google group thread</a>.</p>

<h2>Stupid simple Events sample application</h2>

<p><a href="https://github.com/briannesbitt/PlaySampleWithJWebUnitWithAjax">https://github.com/briannesbitt/PlaySampleWithJWebUnitWithAjax</a></p>

<p>The application is very simple and only has 1 page.  It allows a user to create a new Event (id,title) and uses ajax to submit that to the server.  A notification result (OK,ERROR) is displayed for the user.  All existing Events are listed, and dynamically updated, at the bottom in a simple &lt;ul&gt; list.  The application uses the bundled in-memory database H2 so there really isn't anything to setup or configure.  The json responses from the server are in the following form:</p>

<pre><code class="java">
{ "status": "OK", "msg": "some message" }
{ "status": "ERROR", "msg": "some message" }
</code></pre>

<h2>Try it out!</h2>

<pre><code class="bash">
git clone git://github.com/briannesbitt/PlaySampleWithJWebUnitWithAjax.git
cd PlaySampleWithJWebUnitWithAjax
play autotest
</code></pre>

<p>You can also run <code>play test</code> and then browse to <code>http://127.0.0.1:9000</code> to try it or <code>http://127.0.0.1:9000/@tests</code> to run the tests manually.</p>

<h2>Lets look at the tests</h2>

<p>I have a <code>BaseFunctionalTest</code> class that extends the Play framework <code>FunctionalTest</code>.  This creates the <code>WebTester</code>, configures the default browser to mimic and initializes the base url using <code>setBaseUrl()</code>.  There is a <a href="http://jwebunit.sourceforge.net/quickstart.html">JWebUnit quick start guide</a> if you need to familiarize yourself first.</p>

<pre><code class="java">
public abstract class BaseFunctionalTest extends FunctionalTest
{
   protected WebTester wt;
   protected BrowserVersion defaultBrowserVersion = BrowserVersion.INTERNET_EXPLORER_8;

   @Before
   public void before()
   {
      wt = new WebTester();
      wt.getTestContext().setUserAgent(defaultBrowserVersion.getUserAgent());
      if (wt.getTestingEngine() instanceof HtmlUnitTestingEngineImpl)
      {
         ((HtmlUnitTestingEngineImpl) wt.getTestingEngine()).setDefaultBrowserVersion(defaultBrowserVersion);
      }
      wt.setBaseUrl(getRouteAbsolute("Application.index"));
      wt.getTestingEngine().setIgnoreFailingStatusCodes(false);
   }
   protected String getRouteAbsolute(String action)
   {
      Router.ActionDefinition route = Router.reverse(action);
      route.absolute();
      return route.url;
   }
   protected String getRoute(String action)
   {
      return Router.reverse(action).url;
   }
}
</code></pre>

<p>There are 4 simple tests in the <code>test\ApplicationTest.java</code> file.</p>

<h2>testIndexRendersSuccessfully()</h2>

<pre><code class="java">
@Test
public void testIndexRendersSuccessfully()
{
   wt.beginAt(getRoute("Application.index"));
   wt.assertElementPresent("createEvent");
   assertEquals(wt.getElementById("error").getTextContent(), "");
   assertEquals(wt.getElementById("success").getTextContent(), "");
}
</code></pre>

<p>This first test is a simple test to ensure the index page gets rendered properly and just checks a few html elements on the page.</p>

<h2>testCreateEventFailsWithBlankTitle()</h2>

<pre><code class="java">
@Test
public void testCreateEventFailsWithBlankTitle() throws InterruptedException
{
   wt.beginAt(getRoute("Application.index"));
   wt.setTextField("title", "");
   wt.clickButton("createEvent");

   Thread.sleep(2000); // <--- Required since you have to wait for the round trip !!

   wt.assertTextInElement("error", "Required");
   assertEquals(wt.getElementById("success").getTextContent(), "");
}
</code></pre>

<p>The second test tries to submit the form using ajax with a blank title value.  We want to check the <code>&lt;div id="error"&gt;</code> for the error message, but we have to wait for a length of time to allow the ajax call to complete.  I choose 2 seconds since that <b>seems</b> like a reasonable amout of time.</p>

<h2>testCreateEventSuccessAjaxAsync()</h2>

<pre><code class="java">
@Test
public void testCreateEventSuccessAjaxAsync() throws InterruptedException
{
   wt.beginAt(getRoute("Application.index"));
   wt.setTextField("title", "My New Event");
   wt.clickButton("createEvent");

   Thread.sleep(2000); // <--- Required since you have to wait for the round trip !!

   assertEquals(wt.getElementById("error").getTextContent(), "");
   wt.assertTextInElement("success", "Created Event with Id:");
   assertEquals(1, Event.count());
}
</code></pre>


<p>The third test successfully creates a new Event via ajax.  Again we need to <code>Thread.sleep(2000)</code> to wait for the ajax call to return so we can assert the <code>&lt;div id="success"&gt;</code> gets populated with the success nofication text and that the DB has an Event.</p>

<h2>testCreateEventSuccessAjaxSync()</h2>

<pre><code class="java">
@Test
public void testCreateEventSuccessAjaxSync()
{
   wt.beginAt(getRoute("Application.index"));

   // This will make the ajax call synchronous - no more Thread.sleep() !
   if (wt.getTestingEngine() instanceof HtmlUnitTestingEngineImpl)
   {
      ((HtmlUnitTestingEngineImpl) wt.getTestingEngine()).getWebClient().setAjaxController(new NicelyResynchronizingAjaxController());
   }

   wt.setTextField("title", "My New Event Title");
   wt.clickButton("createEvent"); // <--- ajax call becomes synchronous
   assertEquals(wt.getElementById("error").getTextContent(), "");
   assertEquals(1, Event.count());
   List<Event> events = Event.findAll();
   wt.assertTextInElement("success", "Created Event with Id:" + events.get(0).id);
}
</code></pre>

<p>The final test successfully creates a new Event via ajax, but this time we have setup an instance of <code>NicelyResynchronizingAjaxController</code> as the testing engine ajax controller.  This makes the ajax call synchronous.  This allows us to avoid the unknown length of <code>Thread.sleep()</code> time and we can continue our test ensuring that the <code>&lt;div id="success"&gt;</code> gets populated correctly and infact there is a new Event in the db.</p>

<p>I would of course push this code to the base class but have left it here in the test for the purposes of this sample.</p>

<p>This is not meant to be an exhaustive test suite, but simply serves to show how to setup JWebUnit to process ajax requests synchronously to make your tests more robust and increase their dependability.</p>

<h2>%test.play.pool=2</h2>

<p>Also just thought I would mention this since it took me a moment to realize what was happening when I first started using JWebUnit.  When you run play in dev or test mode it by default only creates the server execution pool with 1 thread.  When I ran my first JWebUnit functional test it worked when testing against the <code>http://www.playframework.org</code> homepage but failed (read hung forever) when I started using <code>http://127.0.0.1:9000</code>.  I realized that the 1 executor thread was responding to my test run and I was causing a deadlock when making the test call back to the server again.  Adding the line <code>%test.play.pool=2</code> to the <code>application.conf</code> was the easy solution.</p>]]></description>
   </item>
      <item>
      <title>My Father Son relationship: a speech to my Dad on his 70th birthday</title>
      <link>http://nesbot.com/2011/10/25/my-father-son-relationship</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Tue, 25 Oct 11 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2011/10/25/my-father-son-relationship</guid>
      <description><![CDATA[<p><i>On Oct 20 my "Toronto Maple Leaf Fan" father had his 70th birthday and this is the speech I gave.</i></p>

<p>We are here today to celebrate my Dad's 70th birthday.  Until a few years ago I was only able to really understand 1/2 of the father/son relationship.  As a kid you don't take time to cherish the little moments in life, but it's a skill we learn as we get older when it takes more than just a teddy bear to cheer us up.  Now that I have 2 sons I find I am remembering and happily reliving all of the moments that my Dad and I shared together and not a day goes by that I don't think about what you have given me.</p>

<p>Everything I do with Jack and with Noah are things that you took the time necessary and taught me how to do.  When Jack and I play hockey I think about all of the times we went together for hours on end to the local rink when you were first teaching me how to skate and later playing in pickup games.  Every time I play now, I still hear your encouraging voice saying "You can do it, keep skating"!  I know you enjoyed it as much as I did.</p>

<p>All the years I played soccer, I had the best coach there was.  We played so many games and enjoyed so many great moments together from winning championships to simply getting an ice cream at DQ after games.  However, I still think the best coaching move you made each year was always picking me first.</p>

<p>I was 13 when I got my first golf set and was eager to play!  I don't think I am going out on a limb saying golf was never your favourite sport.  However, it quickly became important to you, because it was important to me.  Sure enough shortly after you also got a set of golf clubs for, uh, father's day I think eh...not that I had anything to do with that!  And for anyone who knows my parents, they aren't exactly early risers.  But when you needed to be up for 6 AM hockey practices or an 8 AM tee off time on Saturday morning you were always up early and ready to go with me.</p>

<p>There are too many other sports and clubs that we participated in together to mention them all like softball, beavers, cubs ... You always said, "I am going to be at the games anyway, I might as well get involved!".</p>

<p>Part of being a great leader for me meant you always taught me to make my own decisions and think for myself.  Maybe that's why I put my Leaf days behind me and am now a sens fan!</p>

<p>In 2007 the sens made it to the Stanley Cup...has it really been 4 years already?!?...my company had season tickets and got tickets for the Stanley cup.  I got 2 tickets for game 4 here in Ottawa and I knew who I was taking before I even got the tickets.  We had watched Hockey Night in Canada together so many Saturday nights when I was growing up. It made me very happy and proud that I could take you to a Stanley cup game.  It's something that only comes around a handful of times and to share that with you is something special that I will never forget. It's a good thing I am not a Leaf fan otherwise we wouldn't have ever gotten to go!</p>

<p>Besides sports there were a lot of other things you taught me that I now get to reminisce about.  From building decks and fences, to painting or making a very large and heavy gokart, you gave me the knowledge and seemed to have never ending patience that I am sure I tested on a regular basis.  I remember asking ...ok begging...to help put together some new piece of furniture late on a Saturday night after the hockey game was done, partly because I wanted to stay up, but mostly because I enjoyed spending time with and helping my Dad.  Now my oldest son Jack is oh so eager to help me with whatever is next on my honey to do list.  He is right there with a hammer in one hand and bucket loads of naive energy in the other, and I am proud to be able to pass down to him what you passed down to me.</p>

<p>When done right, the life of a parent never ends and sometimes it just gets multiplied by also being a grandparent.  Recently Amy and I had to persevere through a 3 month stay in the hospital with our youngest son Noah.  We could always count on you and Mom to help with Jack or visit me on the weekends at the hospital, when Amy was taking a rare day off.  There was no prying Noah from Mom so she would usually stay in the room holding Noah and you and I would have lunch in the coffee shop or take a walk outside together.  It was a refreshing change during those long days and I thank you for that.</p>

<p>You have given me big foot steps to follow, but I will do my best at passing down the lessons I have learned to Jack and Noah.  Thank you for your guidance and for being such a great influence throughout my life.  I am very lucky to have you as my father and friend.  On behalf of Amy and Noah, Jack and I wish you a happy 70th birthday and I speak for both of us when I say we embrace the learning and pancakes with syrup still to come.</p>]]></description>
   </item>
      <item>
      <title>Play framework accesslog module update</title>
      <link>http://nesbot.com/2011/11/16/play-framework-accesslog</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Wed, 16 Nov 11 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2011/11/16/play-framework-accesslog</guid>
      <description><![CDATA[<p>A few weeks ago my first Play framework module got accepted and published. The module performs request logging similar to an access log file in nginx or apache.  I just released a small update (v1.1) to the module.  It now attempts to create the full log path if it doesn't exist.</p>

<p>This post is not meant to duplicate the documentation I already have written and published on github and playframwork.org.  I will first refer you to those sites and then continue this post with a quick sample application using the module.</p>

<p><a href="http://www.playframework.org/modules/accesslog">http://www.playframework.org/modules/accesslog</a><br/>
<a href="https://github.com/briannesbitt/play-accesslog">https://github.com/briannesbitt/play-accesslog</a></p>

<p>Let's now create a new Play application.</p>

<pre><code class="bash">
play new accessLogSample
cd accessLogSample
</code></pre>

<p>Now add <code>- play -> accesslog 1.1</code> to your <code>conf/dependencies.yml</code> file.</p>

<pre><code class="bash">
play dependencies
play run
</code></pre>

<p>Now load <code>http://127.0.0.1:9000/</code> in your browser.  Thats it! You should see the requests and responses get logged to your configured accesslog file.</p>

<h2>v1.0 Warning</h2>

<p>The initial 1.0 version would have generated the following warning if you did have the full path to the log file pre-created:</p>

<p><code>23:57:55,286 WARN  ~ AccessLogPlugin: No accesslog will be used (cannot open file handle) (Z:\dev\accessLogSample\logs\access.log (The system cannot find the
path specified))</code></p>

<p>I have updated the module to recursively create the directory structure to the configured <code>accesslog.path</code> file provided.  If you use the default config and are running the 1.0 version, all you need to do if you see the warning above is <code>mkdir logs</code> in your project root or better yet just upgrade to the lastest version.</p>

<h2>Logging to Play console</h2>

<p>Although having the log file populated is nice, during dev its also nice to see the logs in the console.  To get this working just add <code>accesslog.log2play=true</code> in your <code>conf/application.conf</code> and restart.  This will cause the logs to be written to the <code>play.Logger</code> at the <code>INFO</code> level so it also relies on your <code>application.log=INFO</code> being set which is the default so for most it will just work.</p>

<h2>Production Usage</h2>

<p>There is nothing special done in the module with respect to performance.  It is threadsafe as the log method is synchronized.  I could have done something more like push the log strings to an in-memory queue and run a seperate thread for the IO, but it wasn't worth the effort.  Logging is done in <code>invocationFinally()</code> so it shouldn't slow the response to the browser as that should already be sent out.  I would recommend using this in dev along with <a href="http://getfirebug.com/">firebug</a> / <a href="http://www.fiddler2.com">fiddler</a> to help debug or track down any issues you might be having.  If you use it in production I would do so only under a watchful eye and for a short amount of time.  For a longer term production logging solution you should setup a reverse proxy like nginx and use it's logging capabilities as described here: <a href="http://wiki.nginx.org/HttpLogModule">nginx HttpLogModule</a>.

<p>And yes I repeated that last part, but its important enough to do so!</p>]]></description>
   </item>
      <item>
      <title>This blog is now running on Play 2.0 BETA</title>
      <link>http://nesbot.com/2011/11/22/now-running-on-play-2-beta</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Tue, 22 Nov 11 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2011/11/22/now-running-on-play-2-beta</guid>
      <description><![CDATA[
<p>Yes my blog is <b>LIVE</b> and yes this is now running on the preview <b>BETA</b> version of the Play framework 2.0.</p>

<h2>Are you crazy?</h2>

<p>The feeling I get from the release is that it's a beta release in terms of framework features but not really from a stability/performance standpoint.  The team behind Play has gathered some great experience from Play 1.X so this is hardly thier first attempt.  I haven't experienced any show stoppers during my use (granted its been short lived) or seen any large issues on the google group besides "when is this going to get implemented".  The reality is that this is my personal blog.  If it instantaneously self combusts for a couple of minutes/hours/days we all shall live ... plus it makes for a great story!</p>

<h2>Some more reasoning... however crazy!</h2>

<p>The framework is built on top of <a href="http://www.jboss.org/netty">netty</a> which has been around for years.  It doesn't automatically give you a home-run (read web framework out of the box) but it does give you an easy stand up double (stable networking layer and http implementation).</p>

<p>Another major portion of a web framework is the template engine.  Play 2.0 includes a powerful Scala-based template engine. The template engine's syntax design was inspired by ASP.NET Razor.  The template engine was first introduced in the Scala version of Play 0.9.1, about 6 months ago.  Sure its integrated into a different engine now, but I suspect it was most likely easier this time around since the core is now developed in Scala while before it was added as a plugin on top of a core Java framework.  This of course doesn't make it bullet proof but its further ahead than having just been developed in the last few weeks for 2.0.</p>

<p>I am not trying to convince anyone to start using this version.  Not surprisingly this seems to be a common question on the google group.  I just know for my personal blog I am ok with <a href="http://www.youtube.com/watch?v=7nqcL0mjMjw" target="_blank">livin' on the edge</a>.  From my current understanding (as mentioned by the project lead) they expect a final version <i>"early next year"</i> with a <i>"first release candidate end of January"</i>. If history is a good indicator (which I think it is) and with the Typesafe announcement (possible dev resources) I am sure the development will move along as smoothly as can be expected.  The first messaging about Play 2.0 was done on Sept 7 and at that time it was said there would be a BETA by end of year. Since then there was a preview released on Oct 25 and the BETA on Nov 16, nicely ahead of schedule.</p>

<h2>How my blog was setup on Play 1.2.X</h2>

<p>The old site was available on github : <a href="http://github.com/briannesbitt/v1.nesbot.com">http://github.com/briannesbitt/v1.nesbot.com</a></p>

<p>
I won't cover every little detail but will focus on the parts that played the largest role in the porting exercise. The actual posts I kept in tag template files in the <code>app/views/tags/posts/</code> directory with a file name format <code>YYYY-mm-dd-slug.html</code>.  The first line of the template source contained a comment that had the title to be used - <code>*{My post title}*</code>. I never bothered creating an admin just for myself which allowed me to just use template files and do anything in the template as necessary (like referencing similar posts in a series etc.).  I had a job that ran <code>@OnApplicationStart</code> that read the files in the directory and loaded all matched files (and parsed the title from the first line) into a <code>ConcurrentOrderedMap&lt;String, Post&gt;</code> which was backed by an ArrayList and HashMap. The Map is actually part of my <a href="https://github.com/briannesbitt/nesbot-commons">nesbot-commons</a> APIs. I created the ConcurrentOrderedMap to allow easy lookups for posts by index (0,1,2,3...) and by slug and both lookups are indexed (read fast).  The concurrency is accomplished using ReentrantReadWriteLock so there really is no contention since all of the writing is done at startup.  To pull in new posts I just restart the server, which is simple and sufficient for my site. At somepoint I could easily create a quick service point that just runs the startup job again.  Most of the features in the nesbot-commons API are available via other public APIs (apache commons, google guava, etc) but I had fun writing them, wrote a build script using Rake (ruby), performed testing and integrated cobertura which was all good learning.</p>

<p>I will now show you snippets from the old routes, controller and template so you will be able to compare later on and see the changes.</p>

<p>The route is obviously meant to match a <code>/2011/11/22/slug</code> format. <i>Don't tell anyone</i> but I ignore the date portions and just do a lookup by slug.  I hate when you visit a blog and there is no date so you can't tell how old the content you are reading is !!  But I digress. :-)</p>

<pre><code class="bash">
GET /{<[0-9]{4}>year}/{<[0-9]{1,2}>month}/{<[0-9]{1,2}>day}/{slug}/?   Application.show
</code></pre>

<p>The controller is simple.  It gets the Post by slug, does a couple of error checks and finally renders the template also passing in the older and newer posts (which must be local variables for that magic to work) which are used for the navigation at the bottom of the post.</p>

<pre><code class="java">
public static void show(Long year, Long month, Long day, String slug)
{
   Post post = Post.findBySlug(slug);

   if (post == null)
   {
      notFound(slug);
   }

   if (!templateExists(PostExtensions.tagName(post)))
   {
      notFound("template for : " + PostExtensions.tagName(post));
   }

   Post older = post.next();
   Post newer = post.previous();

   render(post, older, newer);
}
</code></pre>

<p>The final snippet is from the show.html template. It extends the master template and simply shows the post.  The inclusion of the actual post tag template is easy since Groovy allows the dynamic include of another template by a variables value.</p>

<pre><code class="bash">
&lt;h1>${post.title}&lt;/h1>
&lt;div class="date">${post.prettyUpdated()}&lt;/div>

#{share uTag:'Top',urlimages:urlimages,title:post.title,url:post.fullUrl() /}
#{include post.tagName() /}
#{share uTag:'Bottom',urlimages:urlimages,title:post.title,url:post.fullUrl() /}
</code></pre>

<p>Its all quite simple.  No "real" data source and no html form processing so the move to 2.0 shouldn't be too bad, I think!  The only other part I'll mention at this point is that there is an RSS feed generated as well.</p>

<p><h1>Things I encountered during the conversion to Play 2.0 BETA</h1></p>

<h2>Scala templates</h2>

<p>I have started to do some reading about Scala but my current skills are still to be desired at this point. The templates I needed to port were not hard to write and the early Play 2.0 documentation on github combined with the samples provided (3 complete samples for a BETA... nicely done) gave me enough information that I didn't have any trouble with them. During dev, all of the templates <code>app/views/**/*.scala.html</code> are parsed and compiled to a Scala singleton object.  The old groovy templates from 1.X were only first touched at runtime.  This provides a pretty nice development workflow and the compile errors are generally well displayed.  The only issue I saw was if you have a long line of text, say a paragraph in a blog post, and you forgot to esacpe a <code>@</code> near the end of the line, then the error shows the line but there is no horizontal scrollbar so the actual error is off the page to the right.  You need to view source or use firebug to actually see it.</p>

<p>Writing this post I actually just came across what appears to be an error.  If you have &quot;&quot;&quot; (3 quotes) in your template it fails to compile.</p>

<p>Being a BETA release all of the sugar that was there in 1.X is just not available yet (FastTags, Extensions, absolute reverse routing), but nothing you can't just implement yourself.  You can basically write a Java/Scala class and just statically import it into the template and start calling the methods on it. For example to perform a url encode on a string you can write a <code>public static String urlencode(String s)</code> method in a <code>app/helpers/Html.java</code> file.  To use this function, your template might look like:</p>

<pre><code class="scala">
@(searchTxt: String)

@import helpers.Html._

&lt;a href="http://www.google.com?q=@urlencode(searchTxt)"&gt;Search for @searchTxt via google.&lt;/a&gt;
</code></pre>

<p>Since the templates get compiled down to Scala code, you can overload functions and everything works as expected.  For example to output the "pretty" post date I have these helper functions:</p>

<pre><code class="java">
public static String prettyTimestamp(long ts)
{
   return Dater.create(ts).toString("MMM d, yyyy");
}
public static String prettyTimestamp(Post post)
{
   return prettyTimestamp(post.updated);
}
</code></pre>

<p>The accompanying template would call <code>@prettyTimestamp(post)</code> to display the post date but you can also use the same function if you have a timestamp <code>@prettyTimestamp(post.updated)</code>.  The Dater class is part of nesbot-commons (I have never liked star wars and therefore don't care for joda-time ;).  There is a way to do this in scala where you can actually have the template syntax be <code>@searchTxt.encode</code>.  I haven't bothered to branch over to Scala yet, but I am sure these helpers will be in the framework by the time RC1 is released anyway.  I'll give you one more example for url reverse routing for posts.  Reverse routing for posts is done like <code>@routes.Application.show(year, month, date, slug)</code>.  This is used to link to similar posts and for the next/previous post navigation. Absolute reverse routing is not implemented yet so I had to implement my own (I need the absolute for the RSS feed). Not to mention if you have a post object in the template calling the above routing code in many places doesn't feel very DRY.  I created 2 functions to help out.</p>

<pre><code class="java">
public static String url(Post post)
{
   Dater d = Dater.create(post.updated);
   return routes.Application.show(d.year(), d.month(), d.date(), post.slug).url();
}
public static String urlFull(Post post)
{
   return Config.urlbaseabsoluteNoSlash() + url(post);
}
</code></pre>

<p>This makes post linking simple. After statically importing the Html helper class the home page, for example, can simply do <code>@url(post)</code>.  Wherever an absolute url is required you use the 2nd function, <code>@urlFull(post)</code>.  The Config class I'll talk about in a bit.  It was also mentioned in the google group that a config value might be added to allow us to specify some default classes to import for templates.  This would eliminate the need for the <code>@import helpers.Html.*</code> at the top of each template that makes use of the helpers.</p>

<h2>Blank lines in rendered HTML</h2>

<p>
When I was getting the <code>/rss</code> feed working I kept getting the open/save option in Firefox rather than the nice rss page that is usually shown.  It turns out that there were some blank lines at the top of the rendered xml. For most pages this does not matter. If you generate an RSS page though, blank lines at the top do matter - so it seems.  Tweaking the Scala template a bit I determined:</p>

<ul class="list">
<li>If you just have a simple no args template file then there are no blank lines.</li>
<li>If you specify arguments at the top of the template "@(s : String)" then you will get 1 blank line.</li>
<li>If you start calling layouts... more blank lines.</li>
<li>@import lines don't generate a blank line.</li>
</ul>

<p>At first I used my trusty hammer (you know...the tool that can fix everything!) and hacked up the controller.</p>

<pre><code class="java">
public static Result rss()
{
   response().setContentType("application/rss+xml");
   String body = rss.render(Post.findAll()).body();

   /* HACK TO REMOVE FIRST BLANK LINE */
   char c = body.charAt(0);
   while (c == '\r' || c == '\n')
   {
      body = body.substring(1);
      c = body.charAt(0);
   }
   /* HACK TO REMOVE FIRST BLANK LINE */

   return ok(body);
}
</code></pre>

<p>This worked just fine, but smelled bad.  I looked into the code for the generated Scala template code file <code>target/scala-2.9.1/src_managed</code> and I learned more about the template system which was a win.  In the end I figured out that if you put your content up on the first line after the arguments it prevents the blank line, which even though is a minus for readability, its not that bad and a better solution than the hack above.</p>

<pre><code class="scala">
@(arg : String)&lt;?xml version="1.0" encoding="UTF-8" ?>
</code></pre>

<h2>Application Global settings</h2>

<p>In Play 1.X you could create a job that ran <code>@OnApplicationStart</code> or write a plugin the handled the start/stop events.  In Play 2.0 there is the concept of a Global object that allows you to handle <code>beforeStart()</code>, <code>onStart()</code>, <code>onStop()</code> and some other events for errors.  I used this to trigger the configuration initialization and loading of the post template files.</p>

<h2>Compiling assets</h2>

<p>Just a quick note to say that I had no problems getting the <a href="http://lesscss.org/">LESS</a> styleshseets compiled and routed.  I quickly tried the same with the javascript files but didn't have much luck.  I am using syntaxhighlighter for the code snippets on the site and I think it already does some "require" calls and I kept getting compiler errors.  I left it for now and will revisit later.</p>

<h2>Public assets routing</h2>

<p>If you stick with the defaults here everything works as expected.  I think the syntax is quite cumbersome <code>&lt;img src="@routes.Assets.at("images/play.png")" /></code>. In the future I will wrap this in my own helper function which would then just use the Assets helper anyway but at least centralize it.  The other thing I tried, is I generally prefer to serve images from <code>/images</code>, css from <code>/css</code>, js from <code>/js</code> etc. If you do this you need to add a 2nd parameter, folder, to the at() call.  Its explained on the <a href="https://github.com/playframework/Play20/wiki/AssetsPublic">wiki</a> but I really didn't get it at first glance.  The old routes and syntax for static files seemed easier but this is a small issue in the grand scheme.  Either way once I add my wrappers I will be able to change it easily anyway.</p>

<h2>Configuration for several environments</h2>

<p>I didn't see anything in the wiki yet about this so I wrote a quick interface using the supplied helper Configuration methods.  This is another feature that I am sure will be in for the RC release. There is already a helper <code>play.Configuration.getSub()</code> to get all values in a sub-configuration so I am thinking this will get integrated into the various <code>play.Configuration.getString()</code> methods to see if there is a <code>mode.value</code> or just a value defined.  After a quick look today it appears there is something for this in the Scala API but nothing in the Java API as of yet.</p>

<p>For my purposes I have implemented a Config class. The <code>init()</code> function is called by the <code>Global.beforeStart()</code> handler.</p>

<pre><code class="java">
public class Config
{
   private static Configuration _envConfig;

   public static void init(Configuration configuration)
   {
      _envConfig = isDev() ? configuration.getSub("dev") : configuration.getSub("prod");
   }

   public static boolean isDev()
   {
      return Play.isDev(Play.current());
   }
   public static boolean isProd()
   {
      return Play.isProd(Play.current());
   }
   private static String getString(String key)
   {
      String envValue = _envConfig.getString(key);
      return (envValue != null) ? envValue : Configuration.root().getString(key);
   }

   public static String postsPath()
   {
      return getString("posts.path");
   }
}
</code></pre>

<p>So now you can just call <code>Config.postsPath()</code> and you get either the global value or the environment specific value. In any template you can call <code>@helpers.Config.postsPath</code> or <code>@import helpers.Config._</code> and then <code>@postsPath</code> if the configuration value was required in your templates.</p>

<p>Also from what I can tell the server starts in a particular mode depending on how its initiated.  <code>play run</code> will start a reloading application in DEV mode and <code>play start</code> will start a precompiled application in PROD mode.  If you wanted to add a stage or qa you would have a few options but I think I would do it via an environment variable defined maybe as <code>{application.name}.ENV</code> or something specific like that.  Then just augment the init() function to be a switch and you are all set.  Of course this would only be in your application as I don't think you can pass in a mode yet like how "--%mode" worked for 1.X.</p>

<h2>Where and how I keep the post template files now</h2>

<p>Initially I ported over the code pretty much as is, moving the previous <code>@OnApplicationStart</code> job code to the new <code>Global.beforeStart()</code> handler.  I translated the templates to the new Scala templates and tried running the application.  It failed miserably!  What happens is the <code>app/views/**/*.scala.html</code> DSL templates get compiled via the framework and are managed in the <code>target/scala-2.9.1/src_managed/main/views/html</code> directory.  So my first post <code>app/views/posts/2011-9-7-carpenters-house-last-to-get-attention.scala.html</code> is compiled to <code>target/scala-2.9.1/src_managed/main/views/html/posts/2011-9-7-carpenters-house-last-to-get-attention.template.scala</code>.  Here is a snippet of the compiled Scala template code:</p>

<pre><code class="scala">
package views.html.posts

object 2011-9-7-carpenters-house-last-to-get-attention extends BaseScalaTemplate[play.api.templates.Html,Format[play.api.templates.Html]](play.api.templates.HtmlFormat) with play.api.templates.Template0[play.api.templates.Html] {

    def apply():play.api.templates.Html = {
        _display_ {

          Seq(format.raw/*1.76*/(&quot;&quot;&quot;
      &lt;p>post content is here&lt;/p> &quot;&quot;&quot;))}
    }

    def render() = apply()
}
</code></pre>

<p>The issue I discovered is that the template file name gets used as the compiled Scala object name.  In case you have forgotten, java class naming dictates that a class can not start with a number and "-" is not allowed in the name.  I had to change my filename format so that it would be a valid class name to get it to compile.  I changed the file name format to <code>pYYYY_mm_dd_slug.scala.html</code>. I use "p" to indicate a post but mostly to satisfy the can't start with a number rule.  I changed the "-" as the seperator to "_" as underscores are allowed.  The slug portion also uses "_" to seperate words and I simply replace them in favour of "-" to use in the actual url's produced.  The title is still in the template file as the first line but uses the new comment syntax <code>*@post title@*</code>.  A bit of an aside, when I am working on a new post I go ahead and create the new file but with a prefix of "a_" which will do a few things for me.  Without it showing up on the live site I can go ahead and push it to github so I won't lose anything I write if its not done in one sitting (also allows me to work on it from multiple computers if necessary) and gets it sorted to the top in a directory listing so I can always see which post I am currently working on. I could branch for each new post but that just seems like overkill.  This got the posts being populated and the templates compiling successfully and so I moved on to the controller and rendering.</p>

<p>Finally lets take a look at the same snippets as above for the routes, controller and template but I will also include the Html.java code to show dynamically calling the template render() function.</p>

<p>Only minor syntax changes here.</p>

<pre><code class="bash">
GET /$year<[0-9]{4}>/$month<[0-9]{1,2}>/$day<[0-9]{1,2}>/:slug    controllers.Application.show(year : Long, month: Long, day: Long, slug)
</code></pre>

<p>The controller really didn't change much either.  Besides using the new API for template rendering the only other minor change was not having to create the local variables for <code>older</code> and <code>newer</code> posts to pass to the template as now they are real parameters to the template's render() function.</p>

<pre><code class="java">
public static Result show(Long year, Long month, Long day, String slug)
{
   Post post = Post.findBySlug(slug);

   if (post == null)
   {
      return notFound(notFound.render(slug));
   }

   if (!Html.viewExits(Html.tagName(post)))
   {
      return notFound(notFound.render("template for : " + Html.tagName(post)));
   }

   return ok(show.render(post, post.next(), post.previous()));
}
</code></pre>

<p>In the view I could no longer dynamically include the post template like the previous verison did easily <code>#{include post.tagName() /}</code> thanks to Groovy.  I could however just use reflection to load the class and invoke the render method.  The compiled template is a Scala object.  This represents a singleton in Scala and the methods defined can be called staticly.  Its then just an easy matter of loading the class, getting the declared method and invoking it. Even though I am invoking the template at runtime, all of the posts are still compiled and type checked at compile time.</p>

<p>The template really isn't that different looking.  You see the use of the Scala template <code>@</code> begin the code statements.  You see the <code>prettyTimestamp</code> Html helper being called - it was done with an extension before but wasn't typesafe as it is now.  You can see the share tag being called as before except the arguments are now typed rather than just names.  The <code>helpers.Html.render(post)</code> as seen below is where the post template gets rendered.  It makes a couple of other calls to convert the slug back to the template filename and then passes that on to <code>renderDynamic</code> to perform the invoke.</p>

<pre><code class="scala">
&lt;div class="title">@post.title&lt;/div>
&lt;div class="date">@prettyTimestamp(post)&lt;/div>

@share(post.title, urlFull(post), "Top")
@helpers.Html.render(post)
@share(post.title, urlFull(post), "Bottom")
</code></pre>

<p>And the snippet from Html.java for the helpers.</p>

<pre><code class="java">
public static String view(Post post)
{
   return Strings.format("{0}p{1}_{2}", Strings.replace(Config.postsPath(), "app/views/", "views.html."), Dater.create(post.updated).toString("yyyy_M_d"), post.slug.replace('-', '_')).replace('/', '.');
}
public static play.api.templates.Html render(Post post)
{
   return renderDynamic(view(post));
}
public static play.api.templates.Html renderDynamic(String viewClazz)
{
   try
   {
      Class&lt;?> clazz = Play.current().classloader().loadClass(viewClazz);
      Method render = clazz.getDeclaredMethod("render");
      return (play.api.templates.Html)render.invoke(clazz);
   }
   catch(ClassNotFoundException ex)
   {
      Logger.error("Html.renderDynamic() : could not find view " + viewClazz, ex);
   }
   catch(NoSuchMethodException ex)
   {
      Logger.error("Html.renderDynamic() : could not find render method " + viewClazz, ex);
   }
   catch(IllegalAccessException ex)
   {
      Logger.error("Html.renderDynamic() : could not invoke render method " + viewClazz, ex);
   }
   catch(InvocationTargetException ex)
   {
      Logger.error("Html.renderDynamic() : could not invoke render method " + viewClazz, ex);
   }
   return play.api.templates.Html.empty();
}
</code></pre>

<h2>Deployment</h2>

<p>When executing in DEV mode by using <code>play run</code> from the shell or <code>run</code> from the new Play console I don't think you can change the port it binds to.  If you are using <code>start</code> to execute in PROD mode, it will read the port number from a PORT environment variable if it exists. Of course I am sure that control will be enhanced by the release candidate.  Also I haven't seen a <code>play stop</code> command yet.  For now you can kill the task from the pid in the <code>RUNNING_PID</code> file, simple enough but I am sure a stop will be added.  I use this script to restart the server when I deploy a new blog post.  I have nginx running in front as a reverse proxy and it serves up a simple 50x.html page when the proxy isn't responding - most likely during the few seconds it takes to precompile on startup.</p>

<pre><code class="bash">
#!/bin/sh

cd /vol/www/nesbot.com
git pull

if [ -f RUNNING_PID ]
then
  kill `cat RUNNING_PID`
  rm RUNNING_PID
fi

PORT=9001
export PORT

#play2 stop   #this doesn't exist yet!
play2 clean
play2 start
</code></pre>

<h2>Cannot run program "javac"</h2>

<p>Remember you need to have a JDK installed not just the JRE.  This seems obvious enough now, but at the time it caught me by surprise.  Play 1.X was bundled with the eclipse java compiler so you never needed the JDK and on my live server I had only installed the JRE.  Not a huge deal, just something else to remember and do before hand.</p>

<h2>Useless and unscientific benchmarks</h2>

<p>Well maybe not completely useless as they show a definite consistent trend.  Play 2.0 is faster than Play 1.X.  I would hazard a guess that most of this time is eaten up by the templates being moved from Groovy to Scala.  My guess though is that the engine as a whole will generally scale better.</p>

<p>First I ran some simple benchmarks on my local development machine. I have an Intel Core i7 860 (4 cores/8 threads), 8 GB ram and an OCZ 120 GB SSD and am running WINDOWS 7 x64.</p>

<p>
<code>ab -n 10000 -c 6 http://127.0.0.1:9000/</code><br/>

<table class="bordered">
<tr><th></th><th>1.2.3</th><th>2.0 BETA</th></tr>
<tr><td>Requests/sec</td><td>2,800</td><td>4,000</td></tr>
<tr><td>99% requests done in (ms)</td><td>4</td><td>3</td></tr>
</table>
</p>

<p>Then I tried it with a larger template.</p>

<p>
<code>ab -n 10000 -c 6 http://127.0.0.1:9000/2011/9/20/cobertura-module-tricks-with-the-play-framework</code><br/>

<table class="bordered">
<tr><th></th><th>1.2.3</th><th>2.0 BETA</th></tr>
<tr><td>Requests/sec</td><td>1,000</td><td>1,600</td></tr>
<tr><td>99% requests done in (ms)</td><td>7</td><td>6</td></tr>
</table>
</p>

<p>When I launched the site (this past saturday night) I ran some live benchmarks.  The live site runs on a 2GB <a href="https://www.stormondemand.com/">https://www.stormondemand.com/</a> instance running CentOS 5.4.</p>

<p>
<code>ab -n 10000 -c 6 http://127.0.0.1:9000/</code><br/>

<table class="bordered">
<tr><th></th><th>1.2.3</th><th>2.0 BETA</th></tr>
<tr><td>Requests/sec</td><td>1,200</td><td>3,000</td></tr>
<tr><td>99% requests done in (ms)</td><td>11</td><td>5</td></tr>
</table>
</p>

<p>The 2.0 version on the live server was almost as good as on my development machine, which I'd have to chalk up mostly to Linux vs Windows.  The numbers that surprised me the most were the final ones.  The 2.0 version was dramatically better than the 1.2.3 version on my live linux server.  I thought this was pretty impressive since its only a 2 GB instance with 2 cores (4 threads), it runs 3 other play 1.2.3 sites, a couple of PHP sites, mysql and mongodb.  None of the sites are very busy, but its all running none the less. A <code>more /proc/cpuinfo</code> shows an Intel X3440 @ 2.53 GHz which is actually a 4 core (8 threads) CPU but I believe they use something like XEN to partition the hardware.</p>

<p>All in all I am happy with how things went considering this is just a BETA that was released a month earlier than expected.  I haven't touched the testing framework as of yet (shame on me!) but that will be next along with form processing and handling.</p>

<p>Feel free to ask any specific questions via email/twitter/google group and I'll do my best to answer them.</p>

<p>The full blog code is available on github : <a href="http://github.com/briannesbitt/nesbot.com">http://github.com/briannesbitt/nesbot.com</a>.</p>]]></description>
   </item>
      <item>
      <title>Using morphia with Play 2.0 and the sl4j logging error</title>
      <link>http://nesbot.com/2011/11/28/play-2-morphia-logging-error</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Mon, 28 Nov 11 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2011/11/28/play-2-morphia-logging-error</guid>
      <description><![CDATA[
<p>I am in the middle of another fun side project using <a href="http://playframework.org/2.0">Play 2.0</a> and Scala.  I am (strangely?!?) using <a href="http://code.google.com/p/morphia/">morphia</a> to access <a href="http://mongodb.org">mongoDB</a> as the datastore with my own Scala based wrapper.  Yes I looked at <a href="http://api.mongodb.org/scala/casbah/current/">casbah</a>, <a href="https://github.com/foursquare/rogue">rogue</a>, <a href="https://github.com/novus/salat">salat</a> but came back to morphia in the end since I had used it before.   I'll probably go back to some of those other Scala specific libraries, probaly salat, but it just wasn't my focus this time around.</p>

<p>I came across an issue that boiled down to a logging change from Play 1.X to 2.0.  Its an easy fix actually but the exception was weird (and got worse with subsequent page loads) enough that I'll post it here and hope I can save someone time.</p>

<p>The top of the exception stack that you get looks like this:</p>

<pre><code class="bash">
Caused by: java.lang.IllegalArgumentException: can't parse argument number
   at java.text.MessageFormat.makeFormat(MessageFormat.java:1339) ~[na:1.6.0_23]
   at java.text.MessageFormat.applyPattern(MessageFormat.java:458) ~[na:1.6.0_23]
   at java.text.MessageFormat.<init>(MessageFormat.java:350) ~[na:1.6.0_23]
   at java.text.MessageFormat.format(MessageFormat.java:811) ~[na:1.6.0_23]
   at org.slf4j.bridge.SLF4JBridgeHandler.getMessageI18N(SLF4JBridgeHandler.java:251) ~[jul-to-slf4j.jar:na]
   at org.slf4j.bridge.SLF4JBridgeHandler.callLocationAwareLogger(SLF4JBridgeHandler.java:209) ~[jul-to-slf4j.jar:na]
   at org.slf4j.bridge.SLF4JBridgeHandler.publish(SLF4JBridgeHandler.java:285) ~[jul-to-slf4j.jar:na]
   at java.util.logging.Logger.log(Logger.java:481) ~[na:1.6.0_23]
   at java.util.logging.Logger.doLog(Logger.java:503) ~[na:1.6.0_23]
   at java.util.logging.Logger.logp(Logger.java:672) ~[na:1.6.0_23]
   at com.google.code.morphia.logging.jdk.JDKLogger.log(JDKLogger.java:107) ~[na:na]
   at com.google.code.morphia.logging.jdk.JDKLogger.debug(JDKLogger.java:38) ~[na:na]
   at com.google.code.morphia.mapping.MappedClass.<init>(MappedClass.java:113) ~[na:na]
   at com.google.code.morphia.mapping.Mapper.getMappedClass(Mapper.java:200) ~[na:na]
   at com.google.code.morphia.mapping.Mapper.getCollectionName(Mapper.java:208) ~[na:na]
   at com.google.code.morphia.DatastoreImpl.getCollection(DatastoreImpl.java:546) ~[na:na]
   at com.google.code.morphia.DatastoreImpl.createQuery(DatastoreImpl.java:374) ~[na:na]
   at com.google.code.morphia.DatastoreImpl.find(DatastoreImpl.java:395) ~[na:na]
</code></pre>

<p>Then on the next page reload you start seeing exceptions like this:</p>

<pre><code class="bash">
NoClassDefFoundError: Could not initialize class models.Player$
</code></pre>

<p>Play 2.0 uses slf4j bridge <a href="https://github.com/playframework/Play20/blob/master/framework/play/src/main/scala/play/api/Logger.scala#L166">SLF4JBridgeHandler.install()</a> as it configures the root logger.  This causes morphia to throw errors when the logger is in DEBUG mode.  The last stack trace in morphia code is a call to <a href="http://code.google.com/p/morphia/source/browse/trunk/morphia/src/main/java/com/google/code/morphia/mapping/MappedClass.java#111">log.debug("MappedClass done: " + toString());</a>.  There is a <a href="http://code.google.com/p/morphia/wiki/SLF4JExtension">sl4fj morphia extension</a> that you need to include in your classpath and then ensure you call to register the logger extension at startup and the error no longer happens.  You can put it in a static {} block if you want or the <a href="https://github.com/playframework/Play20/wiki/ScalaGlobal">Global object beforeStart()</a>.</p>

<p>For java the code is:</p>

<pre><code class="java">
MorphiaLoggerFactory.registerLogger(SLF4JLoggerImplFactory.class);
</code></pre>

<p>For Scala the code is:</p>

<pre><code class="scala">
MorphiaLoggerFactory.registerLogger(classOf[SLF4JLogrImplFactory]);
</code></pre>

<p>Depending on where you register the new logger extension you might still see the exception.  The other solution (as provided by <a href="http://software-lgl.blogspot.com/">Green Luo</a> who manages the morphia Play module) is to call the <code>init()</code> which sets the internal <a href="http://code.google.com/p/morphia/source/browse/trunk/morphia/src/main/java/com/google/code/morphia/logging/MorphiaLoggerFactory.java#56">loggerFactory to null</a>.</p>

<pre><code class="java">
MorphiaLoggerFactory.init();
MorphiaLoggerFactory.registerLogger(SLF4JLoggerImplFactory.class);
</code></pre>

   <p>Hopefully I'll launch this side project tonight/tomorrow and I'll post about it like I did about <a href="http://nesbot.com/2011/11/22/now-running-on-play-2-beta">moving my blog to Play 2.0</a>.</p>

<p>For reference I have also posted responses on the morphia group as it has been asked there as well and an invalid bug was logged.</p>

<p>
   <a href="https://groups.google.com/d/topic/morphia/Ad8x1BYqD3w/discussion">https://groups.google.com/d/topic/morphia/Ad8x1BYqD3w/discussion</a><br/>
   <a href="http://code.google.com/p/morphia/issues/detail?id=328">http://code.google.com/p/morphia/issues/detail?id=328</a>
</p>]]></description>
   </item>
      <item>
      <title>Fun Play 2.0 project launch : Sidney Crosby Art Ross Watch and My NHL</title>
      <link>http://nesbot.com/2011/11/29/sidney-crosby-art-ross-watch-mynhl</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Tue, 29 Nov 11 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2011/11/29/sidney-crosby-art-ross-watch-mynhl</guid>
      <description><![CDATA[
<p>This post is meant for 2 audiences.  The first are hockey fans and the second are programmers.  If you are like me and fall into both categories than just keep reading.  If you want to to skip ahead to the programmer portion than <a href="#programmer">click here</a> as the hockey part will be first.</p>

<p>If you want to have a look at the site first, go here : <a href="http://hockey.nesbot.com/" target="_blank">http://hockey.nesbot.com/</a></p>

<p><h1>Hockey Fans : about the site</h1></p>

<h2>Sidney Crosby Art Ross Watch</h2>

<p>Let me start by saying I live in Ottawa, ON, Canada and I am a SENS fan.  Apart from the world jr tournament the first <i>lengthy</i> exposure I had to Crosby was the year the SENS beat the PENS in 5 games on their way to the Stanley cup finals.  I respected Crosby's obvious hockey skills but he was young and got labeled as a "whiner", to the point where it references that reputation on his wiki page and over 1/2 a million google hits for <a href="http://www.google.ca/search?q=crosby+whiner" target="_blank">crosby whiner</a>.  I think this comeback is doing a lot for hockey fans to rid him of that label, I know it has for me.  He has obviously worked hard to come back and has shown it on the ice.  To try and repair the relationship between him and I (ok its really between me and him ;-) I wanted to create a site to track Sidney's progress for what could be a history making season.  The <a href="http://en.wikipedia.org/wiki/Art_Ross_Trophy">Art Ross Trophy</a> is given to the player who leads the league in scoring at the end of the regular season.  Crosby won the trophy in his 2nd season with 120 points as a teenager.  This site will track his progress towards the Art Ross by providing a projection of points at the end of the season for him and the top 10 scoring leaders in the league.  The projection is calculated using the players points/game average (so its accomodates injuries) and the remaining games for their respective teams.</p>

<h2>So where does he rank today?</h2>

<p>Crosby was just today given a 2nd assist from saturday night's game against Montreal so he now officially has 9 points in 4 games which gives him a 2.25 pts/game average.  The penguins have 58 games remaining which puts him on pace for 139 points.  This is 34 points ahead of next best Phil Kessel who has had a 20 game head start.  Kessel has averaged 1.29 pts/game and is projected to get 105 points by season end.  The site is automatically updated often so it will be exciting to watch as the season progresses and Crosby surely continues to rack up the points.</p>

<p><a href="http://hockey.nesbot.com/crosbywatch" target="_blank">http://hockey.nesbot.com/crosbywatch</a></p>

<h2>MyNHL</h2>

<p>I am not a big fan of the current scoring system used by the NHL.  Giving 2 points for a shootout win and the same 2 points for a regulation win seems unfair to me.  Also awarding teams for a loss in overtime or shootout is also unfair in my eyes.  A good example is Detroit and Pittsburgh.  Assuming Detroit wins their next 2 games they would be trailing Pittsburgh by 2 points even though they would have 14 regulation wins to Pittsburgh's 10.</p>

<p>The MyNHL site allows you to configure the number of points awarded for wins, losses, OT wins, OT losses, shootout wins and shootout losses.  I don't sort the teams by division or conference, it is just a list showing where the teams would be with your scoring system.  I also disagree with the division leaders getting ranked 1, 2, 3 in the conference as someday the 3rd division leader will not have enough points to make it into the playoffs but will be 3rd in the conference none the less.  If it were up to me the division leaders would be automatically granted a position in the playoffs but then just get ranked by points.</p>

<p><a href="http://hockey.nesbot.com/mynhl" target="_blank">http://hockey.nesbot.com/mynhl</a></p>

<p><h1><a name="programmer"></a>Programmers : how I made the site</h1></p>

   <p>If you haven't read my first post on Play 2.0 you might want to go back and read through <a href="http://nesbot.com/2011/11/22/now-running-on-play-2-beta">This blog is now running on Play 2.0 BETA</a> as it has some thoughts on the BETA status and its current state.</p>

<p>This is my first attempt at working with Scala and specifically Play with Scala. I did this site to start learning Scala using Play 2.0 and figured I might as well create something more than a hello world!</p>

<p>The site is broken up into 3 controllers for the 3 portions of the site.  The <code>Application</code> controller just outputs the index view and has no logic. The <code>CrosbyWatch</code> controller gathers data and then renders the template.  The third controller, <code>MyNhl</code>, has 2 actions.  The <code>index</code> action gets all the teams and renders the initial template, while the second action, <code>dataTable</code>, parses some querystring data that is ajax posted (or applies defaults) and then generates the data table that will get rendered client side.  This is done twice for the intial page load, once for the official NHL scoring system and once for the MyNHL scoring.  Each change event to the MyNHL scoring configuration triggers another call to <code>dataTable</code> which regenerates the table.  All of the sorting is actually done client side with the <code>jquery.tablesorter</code> plugin.  Of course almost the whole site could have been done just client side but there would not have been much Scala involved in that!</p>

<h2>Automatically updating the stats</h2>

<p>I am using <a href="http://jsoup.org/">http://jsoup.org/</a> to scrape the NHL team and player stats and parse the HTML.  Its a really nice library to use and mimics jquery selectors rather than xpath which was rare in the ones I found.  Sometimes parsing HTML can feel pretty brittle but using jsoup was like a breath of fresh air.  There are 2 pages and a little math involved in extracting the data elements for the teams because most sites group OT losses and shootout losses together and only show wins, losses and OT losses.  I go directly to the Pittsburgh Penguins site for the Crosby specific stats.</p>

<p>The Play 1.X <a href="http://www.playframework.org/documentation/1.2.3/jobs">asynchronous jobs</a> framework is exactly what I would have used to schedule the scraping.  Play 2.0 doesn't have jobs built into it yet so I used the <code>java.util.concurrent.Executors</code> to run the job on a regular schedule.  I looked around for the Scala equivalent but most sites just said to use the java api.  I created a <a href="https://github.com/playframework/Play20/wiki/ScalaGlobal">Global</a> object and used the <code>beforeStart</code> to setup the thread scheduler and the <code>onStop</code> for shutdown.  The mongoDB and morphia intialization code will be talked about in the next section.  As you can see the <code>StatsUpdater</code> runs immediately as there is 0 intial delay and then is scheduled to run every 30 minutes.  The thread pool only has 1 thread since its the only scheduled task in the pool.</p>

<pre><code class="scala">
object Global extends GlobalSettings {
  val executor = Executors.newSingleThreadScheduledExecutor()

  override def beforeStart(app: Application) {
    MongoDB.init("mynhl").mapPackage("models").indexes
    executor.scheduleAtFixedRate(StatsUpdater, 0, Dater.secondsPerMinute*30, TimeUnit.SECONDS)
  }
  override def onStop(app: Application) {
    executor.shutdownNow
  }
}
</code></pre>

<p>The <code>Runnable StatsUpdater</code> is probably not as elegant as you can get with Scala since this is my first time and I am just getting used to all of the sugar provided.  The <code>run()</code> calls the appropriate <code>upate*()</code> methods and catches all exceptions and logs any errors via Play.</p>

<pre><code class="scala">
object StatsUpdater extends Runnable {
  def run() {
    try {
      updateTeams
      updatePlayers
      updateCrosby
    }
    catch {
      case e: Exception => play.Logger.error("Exception caught : " + e.getMessage, e)
    }
  }

  // update methods etc
}
</code></pre>

<h2>Datastore is using morphia and mongoDB</h2>

<p>I am (strangely?!?) using morphia to access mongoDB as the datastore with my own quick and dirty Scala based wrapper. Yes I looked at <a href="http://api.mongodb.org/scala/casbah/current/">casbah</a>, <a href="https://github.com/foursquare/rogue">rogue</a> and <a href="https://github.com/novus/salat">salat</a> but came back to morphia in the end since I had used it before.   I'll probably go back to some of those other Scala specific libraries, probably salat and casbah, but it just wasn't my focus this time around and I learned more by hacking up my own morphia wrapper anyway - how ever terrible it might be.</p>

    <p>The initialization for morphia is done in the <code>Global.beforeStart()</code>. It configures the logger which is what I had an issue with yesterday and prompted <a href="http://nesbot.com/2011/11/28/play-2-morphia-logging-error">using morphia with Play 2.0 and the sl4j logging error</a>. It then creates the Morphia datastore for the database <code>mynhl</code>.  Finally it pre-maps, using reflection, the classes for the <code>Team</code> and <code>Player</code> models.  The morphia wrapper is broken into 2 base classes.  <code>MongoModel</code> is the base class for the model instances and <code>MongoObject</code> is the base class for their accompanying Scala singletons.  This seemed like a logical split to me.  The instance model has all of the save/update/delete methods where the finders/counters are in the singleton.  I also extend the morphia DAO object and added a protected variable to each of the model and singleton.  The helper methods can then use the typed DAO interface rather than having to pass the class type to all of the morphia Datastore calls.  Not all of the helper methods are wrapped but the majority of the basic operations are available.  It needs to be augmented to handle WriteConcerns and return proper WriteResults but for this site its sufficient.</p>

<h2>CrosbyWatch Controller & View</h2>

<p>This controller is pretty simple. It gather the players by projected points and determines if Crosby is in the projected to win by checking the head element.</p>

<pre><code class="scala">
object CrosbyWatch extends Controller {
  def index = Action {
    val players = Player.findAllOrderByProjectedPoints
    val winner = players.head
    Ok(views.html.crosbywatch.index(players, winner.name.equals(Player.CrosbyName), winner.name))
  }
}
</code></pre>

<p>The view is also straight forward.  It uses <code>@if(crosbyToWin) {success} else {error}</code> to set the css class appropriately so if he drops out of 1st place there will be some red on the page.  Otherwise it mainly loops over the players and generates the necessary rows in the table.</p>

<p>I chose to use the <code>@players.map { player => block }</code> syntax.  I could also use <code>@for(player <- players) {}</code>.  There are other syntax that could be used for looping over the players.  If you wanted to display a counter you could do <code>@for(i <- 0 until players.size-1) {}</code>.</p>

<h2>MyNhl Controller</h2>

<p>First the <code>index</code> action simply renders the template passing in a <code>Seq[Team]</code> to populate the drop down for selecting your favourite team.  Then it uses the <code>pointsConfig.scala.html</code> tag to render the points config section for the NHL and one that allows the user to configure their scoring system.  Nothing too complicated yet.  On <code>document.ready</code> a few things happen.  Event handlers are setup to highlight the users favourite team when the drop down changes.  Also when any scoring configuration value is changed for the user scenario it makes an ajax call to the server action <code>MyNhl.dataTable()</code> sending in all of the new point parameters.  The server action parses the querystring variables and renders the template.  This generates the standings table and calculates the points for each team as it is rendered using the parsed querystring values.  The sample provided in the Play 2.0 wiki for parsing querystring variables is shown below.  Its done like this because the querystring entries are <code>Seq[String]</code> in order to handle multiple values per variable name.</p>

<pre><code class="scala">val name = request.queryString.get("name").flatMap(_.headOption)</code></pre>

<p>This is pretty verbose so I wrapped it in a ControllerHelper parse function.  I also needed to parse Ints from the String values so I added those as well while handling improper number formatting.  There is probably a more elegant way to get this done but this was easy enough for now.  I tried a few times with the new form handling as indicated <a href="https://github.com/playframework/Play20/wiki/ScalaForms">on the wiki</a> but none of the samples from there worked for me and the majority I couldn't even get to compile.</p>

<h2>Wrap Up</h2>

<p>I think that wraps up this post and project.  I'll be following Sidney's progress this season to see if he can capture the Art Ross even in this era of lower scoring.  As for the programming side, using the Scala API was certainly tougher for me compared to the Java API and my Scala skills have a long way to go.  I struggle with the syntax but also structuring the code to be more functional is still a bit of a mind shift for me that will just take some time.</p>

<p>As always catch me on email/twitter/comments/google group to ask specific questions and I'll do my best to answer them.</p>

<p>The full site code is available on github : <a href="http://github.com/briannesbitt/hockey.nesbot.com">http://github.com/briannesbitt/hockey.nesbot.com</a>.</p>]]></description>
   </item>
      <item>
      <title>CoffeeScript : Why is function binding not the default?</title>
      <link>http://nesbot.com/2012/1/20/CoffeeScript-why-is-function-binding-not-the-default</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Fri, 20 Jan 12 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2012/1/20/CoffeeScript-why-is-function-binding-not-the-default</guid>
      <description><![CDATA[
<p>As of a few days ago I started to play around with <a href="http://coffeescript.org/" target="_blank">CoffeeScript</a> and <a href="http://nodejs.org/" target="_blank">node.js</a>.  Sure I have used JavaScript in the past, like everyone else, but I have never used it enough or taken the time to fully understand the commonly misunderstood scope / context / prototype aspects of the language.  If you don't yet understand it, I direct you to the plethera of <a href="http://www.digital-web.com/articles/scope_in_javascript/" target="_blank">articles</a> about the topic.</p>

<p>I wanted to talk about the syntax subtlety of <code>-></code> vs <code>=></code>.  The CoffeeScript site briefly mentions it as <a href="http://coffeescript.org/#fat_arrow" target="_blank">function binding</a>, aka the Fat Arrow.  Using <code>=></code> ensures that the <code>this</code> context is always the same as when the function was defined, rather than in the context of the object it is currently attached to.  As the site mentions the fat arrow is particullary helpful when using callbacks, of which you will be using a "few" ;).  I think this is probably the most common mistake when first programming JavaScript / CoffeeScript.  You make a function call passing a callback which references <code>this</code> and just expect it to work... surprise!</p>

<p>Its a very subtle difference and most resources skim over the subject or simply ignore it. The free book, <a href="http://arcturo.github.com/library/coffeescript/index.html" target="_blank">The Little Book on CoffeeScript</a>, has a chapter on <a href="http://arcturo.github.com/library/coffeescript/03_classes.html" target="_blank">classes</a> and does a good job explaining the important syntax difference.</p>

<p>I am not the only one who has <a href="http://twitter.com/#!/karlseguin/status/160200811501203456" target="_blank">mentioned this</a>.  I guess the argument is that you can generally avoid the extra call to <code>__bind</code> because some/most of your functions may never be used in a different context and the <code>this</code> scope will always be the same. Thats fine, but this creates many inconsistencies in the code, and for what real benefit?  While I agree there is merit to having the deeper understanding of when to use <code>=></code> vs <code>-></code> properly, I tried to figure out why the unexpected has been adopted as the default.</p>

<h2>Why not show the fat arrow some love?</h2>

<p>The most widely found explanation says to not use it all the time for performance reasons.  Everyone seems to just say ok, makes sense, in the name of performance I'll just use <code>-></code> as the standard and remember to use the fatty <code>=></code> when I need to.  Inevitably you will forget and waste time tracking it down.  Is this potential premature optimization worth the inconsistencies and unexpected behaviour? This smells of my old PHP days when everyone would <b>always</b> use single quotes for strings unless of course you had to inject a variable, then you would drop back to double quotes.  I also remember even Facebook developers saying they didn't worry about the type of quotes they used - of course they "simply" built a <a href="https://github.com/facebook/hiphop-php" target="_blank">PHP to C++ compiler</a> to overcome their challenges.</p>

<h2>Performance? Really?</h2>

<p>To see if the madness should continue in the name of performance I have created a simple little benchmark.</p>

<pre><code class="coffeescript">
class FunctionBinding
  constructor: ->

  thisIsNotBound: ->

  thisIsBound: =>
</code></pre>

<p>You can see below that the compiled JavaScript wraps the <code>thisIsBound</code> function with the <code>__bind</code> call to bind the <code>this</code> context for all calls to that function.  This is where the extra overhead comes from.</p>

<pre><code class="coffeescript">
(function() {
  var FunctionBinding, fb, i,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  FunctionBinding = (function() {

    function FunctionBinding() {
      this.thisIsBound = __bind(this.thisIsBound, this);
    }

    FunctionBinding.prototype.thisIsNotBound = function() {};

    FunctionBinding.prototype.thisIsBound = function() {};

    return FunctionBinding;

  })();

}).call(this);
</code></pre>

<p>Here is the benchmark code that executes the two functions and performs the necessary timing thanks to the node.js STDIO api console.time() and console.timeEnd(), that according to <a href="https://github.com/joyent/node/blob/master/lib/console.js" target="_blank">console.js</a> is just a simple wrapper on <code>Date.now()</code>.</p>

<pre><code class="coffeescript">
fb = new FunctionBinding()

console.time('thisIsNotBound');
fb.thisIsNotBound() for i in [1..1000000]
console.timeEnd('thisIsNotBound');

console.time('thisIsBound');
fb.thisIsBound() for i in [1..1000000]
console.timeEnd('thisIsBound');
</code></pre>

<p>I first ran this with 10, 100, 1000, 10000 iterations but both timings were 0ms throughout.  It wasn't until I got to the 100k and 1 M mark that I saw real numbers.  These are averages of about 10 runs each.

<table class="bordered">
   <tr><th>console.time('marker')</th><th>100k</th><th>1 M</th></tr>
   <tr><td>thisIsNotBinded</td><td>1 ms</td><td>10 ms</td></tr>
   <tr><td>thisIsBinded</td><td>5 ms</td><td>22 ms</td></tr>
</table>

</p>

<p>Looking at the numbers you could make the argument that it takes over twice as long to execute the function with the <code>__bind</code> compared to without.  That would be a fair statement.  I think the numbers also show that the inconsistency in the code and potential for unexpected behaviour this causes is not worth the negligable performance improvement.  After running this I can confidently say that a 12 ms difference on 1 M functions calls is most definitly a shallow over optimization.</p>

<h2>What about memory?</h2>

<p>From what I know so far the methods and properties of the prototype object are not duplicated for each instance and therefore don't add memory overhead with each instance.  The binding code from above adds an instance function to call the prototype with the proper <code>this</code> scope.  This would add overhead which would be a reason to not use unnecessarily.</p>

<h2>Enjoying the tangent</h2>

<p>Don't get me wrong here.  Despite this post, I am enjoying my current tangent.  I am experiencing first hand the positive productivity and conciseness of CoffeeScript and the single threaded event loop of node.js.  I see another blog rewrite in my future... <a href="http://expressjs.com/" target="_blank">express.js</a> anyone!</p>

<p>CoffeeScript is only one of the many projects listed on the <a href="http://altjs.org/">altJS</a> page.  Some of those are fairly interesting but it seems CoffeeScript is the most popular, at least according to github.</p>

<p>Are you drinking the new kool-aid? uh Java? I mean Coffee?</p>












































]]></description>
   </item>
      <item>
      <title>A "quick" microbenchmark</title>
      <link>http://nesbot.com/2012/2/8/a-quick-microbenchmark</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Wed, 08 Feb 12 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2012/2/8/a-quick-microbenchmark</guid>
      <description><![CDATA[
<p>The other day I decided to do some microbenchmarking across several different languages.  I used an array of 1 M integers and applied the <a href="http://en.wikipedia.org/wiki/Quicksort">quicksort</a> sorting algorithm as the test code and also included the native language sort routines where applicable.</p>

<p>I wrote the runner using <a href="http://coffeescript.org/#cake">Cake</a> and <a href="http://coffeescript.org">Coffeescript</a> which compiles to Javascript and runs on <a href="http://nodejs.org/">node.js</a>.  Cake is a very simple build system and is similar to make/rake, as you probably already guessed.</p>

<p>Each respective test will run the sort algorithm 5 times (some only 3 because they take so long already it doesn't matter) and the minimum execution time is printed.  I ran each one a few times and took an eyeball average of those runs.  I am not that interested in a +/- of a few milliseconds when sorting 1 M integers.  I am way more interested in orders of magnitude.</p>

<h2>Results</h2>

<p><table class="bordered">
   <tr><th></th><th>Language</th><th>Version</th><th>Time in milliseconds</th></tr>
   <tr><td>1</td><td>C++</td><td>MS 16.00.30319.01 for 80x86</td><td>75</td></tr>
   <tr><td>2</td><td>C# Array.Sort()</td><td>.NET 3.5</td><td>100</td></tr>
   <tr><td>3</td><td>Java</td><td>1.6.0_23</td><td>105</td></tr>
   <tr><td>4</td><td>Groovy api (aka java)</td><td>1.8.5</td><td>110</td></tr>
   <tr><td>5</td><td>Java Arrays.sort()</td><td>1.6.0_23</td><td>121</td></tr>
   <tr><td>6</td><td>C#</td><td>.NET 3.5</td><td>126</td></tr>
   <tr><td>7</td><td>Scala</td><td>2.9.1.final</td><td>128</td></tr>
   <tr><td>8</td><td>Node.js (v8)</td><td>0.6.7</td><td>175</td></tr>
   <tr><td>9</td><td>Chrome JavaScript</td><td>16.0.912.77</td><td>182</td></tr>
   <tr><td>10</td><td>Ruby api array.sort!</td><td>1.9.2p290</td><td>250</td></tr>
   <tr><td>11</td><td>Firefox JavaScript</td><td>10.0</td><td>271</td></tr>
   <tr><td>12</td><td>IE JavaScript</td><td>9.0.8112.16421</td><td>307</td></tr>
   <tr><td>13</td><td>IE JavaScript api sort()</td><td>9.0.8112.16421</td><td>375</td></tr>
   <tr><td>14</td><td>Node.js (v8) api sort()</td><td>0.6.7</td><td>480</td></tr>
   <tr><td>15</td><td>Chrome JavaScript api sort()</td><td>16.0.912.77</td><td>520</td></tr>
   <tr><td>16</td><td>Python api sort()</td><td>3.1.3</td><td>814</td></tr>
   <tr><td>17</td><td>PHP api sort()</td><td>5.3.8</td><td>1441</td></tr>
   <tr><td>18</td><td>Firefox JavaScript api sort()</td><td>10.0</td><td>3490</td></tr>
   <tr><td>19</td><td>Ruby</td><td>1.9.2p290</td><td>3520</td></tr>
   <tr><td>20</td><td>Groovy</td><td>1.8.5</td><td>4100</td></tr>
   <tr><td>21</td><td>Python</td><td>3.1.3</td><td>8100</td></tr>
   <tr><td>22</td><td>PHP</td><td>5.3.8</td><td>9700</td></tr>
</table></p>

<h2>Things I will take away from this exercise</h2>

<p>Switching between too many languages during a day is tough and not very efficient.  I haven't done much coding in some of these languages, or not at least for awhile.  I didn't try to use the adopted paradigms in each language.  I did try to keep the overall structure the same for each language.  When you do a google search for quicksort some of the hits for ruby, python, javascript and scala show these "elegant" 1-3 liners of code that make me think I am looking at perl.  Needless to say, I tried a few but they ran quite a bit slower than my bloated version.  Thats not to say that some performance tuning could be done for each language's nuances, but as I mentioned, I am interested in the orders of magnitude comparison rather than a pure speed test.</p>

<p>It was interesting to see how easy some of the features were to find in some languages compared to others.  Command line parameters, random numbers, benchmarking code etc.  Lets take a look at command line parameters in each language.  They are all similar (some variation of an arg[sv] array) but yet different (array offset, parsing, brackets, semi-colon).  Its these subtle differences that make a lot of language context switching difficult.</p>

<p><pre>
C++                      int len = atoi(argv[1]);
C#                       var len = int.Parse(args[0]);
java:                    int len = Integer.parseInt(args[0]);
scala:                   val len = Integer.parseInt(args(0))
php:                     $len = $argv[1];
node.js (coffeescript):  len = process.argv[2]
groovy:                  len = args[0].toInteger()
python:                  alen = int(sys.argv[1])     # len is a reserved word
ruby:                    len = ARGV[0].to_i
</pre></p>

<p>A small but effective change included changing <code>pivot = arr[(left+right) / 2]</code> to <code>pivot = arr[(left+right) >> 1]</code>.  In some languages it generated a noticeable increase in performance.  As well it prevented a necessary cast/floor to an int preventing an array lookup of arr[3.5].</p>

<p>Pythons top google links are tied to v2 rather than v3.  Using the old print statement rather than the print() function is pretty frustrating as you view the examples from google and the code seems correct.  The error message was not at all helpful either.  I have seen this in other languages/frameworks as well.</p>

<p>Then we have the browser wars, aka the js engine war.  Chrome posted the best time for the quicksort.  For some reason I was expecting some overhead compared to node.js but the in browser version was pretty much identical in both test cases.  IE was the most consistent and by far had the best time using the Array API sort().  Firefox was really slow on the API call... no idea why.  It was slow enough that I actually got the warning saying the script was running too long.  During the algorithm Firefox was "Not Responding" as well.  I didn't bother running the code in older versions as that wasn't the goal of this exercise.</p>

<p>Consective runs in IE and FireFox produced consistent results.  However, this was not true for Chrome. Chrome's performance decreased by about double for the second run and a little more after that to what seemed to be a ceiling.  It probably has to do with GC since on a page refresh the time returned back to the fast time.</p>

<p>Groovy gets to piggy back off of the JVM for API calls.</p>

<p>Most of the API sorts were faster.  This is not surprising since the api would generally be running in the interpreters native language and are generally written in c++ so the sorts are running native code at that point.  I was surprised that the quicksort algorithm was faster than the API calls for Java and JavaScript.  In Java it is somewhat negligible and if you look at the source the Arrays sort() API is a "tuned" quicksort.  Without spending too much time on it, it <a href="http://code.google.com/p/v8/source/browse/trunk/src/array.js#776">appears that the v8 implementation</a> is doing a Quicksort written in js but makes extra calls to the required compare function among other things.  The compare is necessary as by default the method sorts the elements alphabetically which is obviously not what we wanted.  I assume this is where the overhead comes from, but that seems expensive as its almost 3x longer.</p>

<p>I was also surprised at how well all of the JavaScript engines did compared to the other main stream (server) languages.  The node.js v8 implementation was 10x - 25x faster than most of them and was less than 2x Java/C#.</p>

<p>You can view the code for each implementation on <a href="https://github.com/briannesbitt/QuicksortMicrobenchmark">github</a>.</p>

<p>Although I did have the idea before seeing this, the following blog post provided some good information <a href="http://stronglytypedblog.blogspot.com/2009/07/java-vs-scala-vs-groovy-performance.html">http://stronglytypedblog.blogspot.com/2009/07/java-vs-scala-vs-groovy-performance.html</a></p>

   <p class="quote">You can see the results with PHP 5.4 ... <a href="http://nesbot.com/2012/5/24/a-quick-microbenchmark-update-PHP-5-4">A "quick" microbenchmark update PHP 5.4</a></p>
]]></description>
   </item>
      <item>
      <title>A "quick" microbenchmark update PHP 5.4</title>
      <link>http://nesbot.com/2012/5/24/a-quick-microbenchmark-update-PHP-5-4</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Thu, 24 May 12 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2012/5/24/a-quick-microbenchmark-update-PHP-5-4</guid>
      <description><![CDATA[
<p class="quote">This is a follow up to <a href="http://nesbot.com/2012/2/8/a-quick-microbenchmark">A "quick" microbenchmark</a>... you may want to go and read that first.</p>
<p>With the <a href="http://php.net/releases/5_4_0.php">release of PHP 5.4</a> being toted as a "significant performance improvement" I thought it might be fun to go back and run the quicksort benchmark against the new release.  I upgraded to 5.4.3 on my local machine and ran the tests.</p>

<h2>Results</h2>

<p><table class="bordered">
   <tr><th></th><th>Language</th><th>Version</th><th>Time in milliseconds</th></tr>
   <tr><td>1</td><td>C++</td><td>MS 16.00.30319.01 for 80x86</td><td>75</td></tr>
   <tr><td>2</td><td>C# Array.Sort()</td><td>.NET 3.5</td><td>100</td></tr>
   <tr><td>3</td><td>Java</td><td>1.6.0_23</td><td>105</td></tr>
   <tr><td>4</td><td>Groovy api (aka java)</td><td>1.8.5</td><td>110</td></tr>
   <tr><td>5</td><td>Java Arrays.sort()</td><td>1.6.0_23</td><td>121</td></tr>
   <tr><td>6</td><td>C#</td><td>.NET 3.5</td><td>126</td></tr>
   <tr><td>7</td><td>Scala</td><td>2.9.1.final</td><td>128</td></tr>
   <tr><td>8</td><td>Node.js (v8)</td><td>0.6.7</td><td>175</td></tr>
   <tr><td>9</td><td>Chrome JavaScript</td><td>16.0.912.77</td><td>182</td></tr>
   <tr><td>10</td><td>Ruby api array.sort!</td><td>1.9.2p290</td><td>250</td></tr>
   <tr><td>11</td><td>Firefox JavaScript</td><td>10.0</td><td>271</td></tr>
   <tr><td>12</td><td>IE JavaScript</td><td>9.0.8112.16421</td><td>307</td></tr>
   <tr><td>13</td><td>IE JavaScript api sort()</td><td>9.0.8112.16421</td><td>375</td></tr>
   <tr><td>14</td><td>Node.js (v8) api sort()</td><td>0.6.7</td><td>480</td></tr>
   <tr><td>15</td><td>Chrome JavaScript api sort()</td><td>16.0.912.77</td><td>520</td></tr>
   <tr><td>16</td><td>Python api sort()</td><td>3.1.3</td><td>814</td></tr>
   <tr><td>17</td><td>PHP api sort()</td><td>5.3.8</td><td>1441</td></tr>
   <tr><td>18</td><td>PHP api sort()</td><td>5.4.3</td><td>1516</td></tr>
   <tr><td>19</td><td>Firefox JavaScript api sort()</td><td>10.0</td><td>3490</td></tr>
   <tr><td>20</td><td>Ruby</td><td>1.9.2p290</td><td>3520</td></tr>
   <tr><td>21</td><td>Groovy</td><td>1.8.5</td><td>4100</td></tr>
   <tr><td>22</td><td>PHP</td><td>5.4.3</td><td>5302</td></tr>
   <tr><td>23</td><td>Python</td><td>3.1.3</td><td>8100</td></tr>
   <tr><td>24</td><td>PHP</td><td>5.3.8</td><td>9700</td></tr>
</table></p>

<h2>Performance improvement? Yes!</h2>

<p>The PHP api version was the same as expected.  I didn't look at the source but I would not have expected the sort algorthim to have been changed.  As you can see though, the implemented version was "significantly" faster as promised... a whopping 45% faster!  That is quite the improvement indeed.  There are some other breaking compatibility changes though to be aware of.  Anyone still relying on <code>register_globals</code> or <code>magic_quotes</code> please step forward !!</p>

<p>As before you can view the code for each implementation on <a href="https://github.com/briannesbitt/QuicksortMicrobenchmark">github</a>.</p>]]></description>
   </item>
      <item>
      <title>PHP on a diet : Up and running with Slim</title>
      <link>http://nesbot.com/2012/6/8/PHP-on-a-diet-up-and-running-with-slim</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Fri, 08 Jun 12 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2012/6/8/PHP-on-a-diet-up-and-running-with-slim</guid>
      <description><![CDATA[
<p>It has been said that if there are <code>n</code> PHP developers in the world then there are <code>n+1</code> PHP frameworks.  While that is most likely undeniably true, I have been perusing the so-called micro frameworks lately of which most are inspired (at least in part) by <a href="http://www.sinatrarb.com/">sinatra</a>.  I tend to enjoy working with the micro frameworks as they typically don't get in your way but just gently get you going.  They don't force a whole stack on you as you generally select your best components (view engine, datastore, etc) and piece them together.  For me it helps to quickly gain a good understanding of the framework and its inner workings and makes it easier to go through its source since its not trying to be everything to everyone. On the <a href="http://www.slimframework.com/">Slim</a> homepage it even says, and I believe it to be true so far... </p>

<p class="quote">"The Slim micro framework is everything you need and nothing you don't."</p>

<p>Up until recently getting a PHP site running locally required the use of apache (using wammp/xampp), nginx or some other local webserver.  With the release of 5.4 a development server is now included in PHP and makes using it locally a breeze.  Even though it was introduced in 2010 I recently came across the Slim Framework.  This post will quickly get you up and running with Slim using <a href="http://getcomposer.org/">composer</a> and the new internal development server.</p>

<pre><code class="bash">
mkdir slimapp
cd slimapp
curl -s http://getcomposer.org/installer | php
</code></pre>

<p>Next create a <code>composer.json</code> file in the web root that indicates your dependency on Slim:</p>

<pre><code class="json">
{
   "require": {"slim/slim": "1.6.*"}
}
</code></pre>

<p>Next we kick off the install of Slim via composer and start the development server:</p>

<pre><code class="bash">
php composer.phar install
php -S 127.0.0.1:80
</code></pre>

<p>There is a nice feature in the PHP 5.4+ development server that helps us out when using friendly urls.</p>

<p class="quote">If a URI request does not specify a file, then either index.php or index.html in the given directory are returned.</p>

<p>As long as we use friendly urls and name our bootstrap file <code>index.php</code> then we can start the development server in our web root and it will all just work.  For those of you who want to use <code>app.php</code>, <code>router.php</code> or something else, it also has the ability to accept another command line parameter to act as a router script.  You can read more about it <a href="http://php.net/manual/en/features.commandline.webserver.php">here</a>.</p>

<p>Finally, create an <code>index.php</code> with the following contents:</p>

<pre><code class="php">
&lt;?
require 'vendor/autoload.php';
$app = new Slim();

$app->get('/', function () {
   echo "Hello World!";
});

$app->run();
</code></pre>

<p>Then goto <code>http://127.0.0.1</code> in your browser and you should see <code>Hello World!</code>.</p>

<p>You can expect more from me on using Slim and you can read more about this micro framework <a href="http://www.slimframework.com/">here</a>.</p>]]></description>
   </item>
      <item>
      <title>Slim wildcard routes via route middleware</title>
      <link>http://nesbot.com/2012/6/18/slim-wildcard-routes-via-route-middleware</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Mon, 18 Jun 12 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2012/6/18/slim-wildcard-routes-via-route-middleware</guid>
      <description><![CDATA[
<p>As I dig further into the <a href="http://slimframework.com">Slim framework</a> I started reviewing some of the community forum questions.  A fun way to both learn and help is to answer questions from users.  I think its one of the best ways to contribute back as it helps increase the audience of the framework.  It also aleviates the main author from being the only one having to do it all the time.</p>

<p>This morning I read the following question about a wildcard catchall route, <a href="http://help.slimframework.com/discussions/questions/230-can-i-have-a-get-request-with-variable-number-of-parameters-in-the-url">Can I have a GET request with variable number of parameters in the url?</a>  It seems this is something the framework currently doesn't support but is potentially slated for a 1.7 release.  In the meantime I thought a simple solution might be to use route conditions in combination with route middleware to parse the incoming parameter into an array for us.  Lets see how we can get this done in a generic reusable fashion.</p>

<p>If you don't know what <a href="http://www.slimframework.com/documentation/stable#routing-conditions">route conditions</a> and <a href="http://www.slimframework.com/documentation/stable#routing-middleware">route middleware</a> are for the Slim framework, I suggest you go and read about them first.</p>

<p>The GET request the user wants to parse is <code>http://hostname/api/getitems/seafood/fruit/meat</code>.  They want to get the <code>seafood</code>, <code>fruit</code> and <code>meat</code> part as an array.  Those parameters are also wildcard in length which means there are a variable number of them, so it might be shorter like <code>http://hostname/api/getitems/seafood</code> or longer like <code>http://hostname/api/getitems/seafood/fruit/apples/bananas/chocolate</code>.</p>

<p>We can start by setting up our route and applying a catch all regular expression to the route conditions.</p>

<pre><code class="php">
$app->get('/api/getitems/:items', function ($items) use ($app) {
   echo $items;
})->conditions(['items' => '.+']);
</code></pre>

<p>When this route is matched the <code>$items</code> parameter will be a string that contains the remainder of the GET request URL.  If we were to load the urls from earlier we would get the following output:</p>

<pre><code class="bash">
seafood/fruit/meat
seafood
seafood/fruit/apples/bananas/chocolate
</code></pre>

<p>Since we used a <code>+</code> in our condition regular expression we don't have to worry about handling a blank string as that won't match our route.  So no we can use a route middleware to perform the <code>explode</code> on our string.  We use PHP's closure support to wrap an anonymous function while passing in the name of the parameter we want parsed.  In our example that name is <code>items</code> as seen above.</p>

<p>We need access to the current route that was matched to read it's parameters.  This didn't seem to be easily done except after looking at the source for the <code>Slim_Route</code> I saw that the route middleware is called with three parameters.  The <code>Slim_Http_Request</code>, <code>Slim_Http_Response</code> and the currently matched <code>Slim_Route</code>.</p>

<p>So here is our middleware callable.</p>

<pre><code class="php">
$parseWildcardToArray = function ($param_name) use ($app) {
   return function ($req, $res, $route) use ($param_name, $app) {

      $env = $app->environment();
      $params = $route->getParams();

      $env[$param_name.'_array'] = array();

      //Is there a useful url parameter?
      if (!isset($params[$param_name]))
      {
         return;
      }

      $val = $params[$param_name];

      //Handle  /api/getitems/seafood//fruit////meat
      if (strpos($val, '//') !== false)
      {
         $val = preg_replace("#//+#", "/", $val);
      }

      //Remove the last slash
      if (substr($val, -1) === '/')
      {
         $val = substr($val, 0, strlen($val) - 1);
      }

      //explode or create array depending if there are 1 or many parameters
      if (strpos($val, '/') !== false)
      {
         $values = explode('/', $val);
      }
      else
      {
         $values = array($val);
      }

      $env[$param_name.'_array'] = $values;
   };
};
</code></pre>

<p>Its more preventitive code than real code.  The comments above indicate the checks in place.</p>

<p>From what I can tell from the Slim source there is no way to inject a new parameter back into the <code>$route->params</code>.  So for now this code injects the newly parsed array into an environment variable for the route to read.  With this in place we can now augment our route to use the middleware and access the newly created array via the environment.</p>

<pre><code class="php">
$app->get('/api/getitems/:items', $parseWildcardToArray('items'), function ($items) use ($app) {
   $env = $app->environment();
   var_dump($env['items_array']);
})->conditions(['items' => '.+']);
</code></pre>

<p>This now prints the following arrays for the same three urls as before:</p>

<pre><code class="bash">
array(3) { [0]=> string(7) "seafood" [1]=> string(5) "fruit" [2]=> string(4) "meat" }
array(1) { [0]=> string(7) "seafood" }
array(5) { [0]=> string(7) "seafood" [1]=> string(5) "fruit" [2]=> string(6) "apples" [3]=> string(7) "bananas" [4]=> string(9) "chocolate" }
</code></pre>

<p>Also, if you are using PHP 5.4+ and what to make use of array dereferencing you can change the above route to be one line like so:</p>

<pre><code class="php">
$app->get('/api/getitems/:items', $parseWildcardToArray('items'), function ($items) use ($app) {
   var_dump($app->environment()['items_array']);
})->conditions(['items' => '.+']);
</code></pre>

<p>As mentioned this could be better if the route middleware was able to inject the new array back into the parameters rather than storing it into the <code>environment</code>.  For now this is an easy solution to implement and is reuseable until the feature is added to the framework itself.</p>

   <p class="quote">Read the follow up to see how it was improved in conjuction with the 1.6.4 release... <a href="http://nesbot.com/2012/7/3/slim-wildcard-routes-improved">Slim wildcard routes improved</a></p>
]]></description>
   </item>
      <item>
      <title>Multilingual site using Slim</title>
      <link>http://nesbot.com/2012/6/26/multilingual-site-using-slim</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Tue, 26 Jun 12 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2012/6/26/multilingual-site-using-slim</guid>
      <description><![CDATA[
<p>A question entitled <a href="http://help.slimframework.com/discussions/questions/244-multilingual-site-with-slim">Multilingual site</a> with <a href="http://slimframework.com">Slim</a> was posted to the <a href="http://help.slimframework.com/">help forum</a> the other day.  Here is my take on how I would start to create such an application with 3 pages: Home, About and Login.</p>

<h2>Overview</h2>

<p>We will start by looking at how the current active language is parsed and extracted from the requested URI using a <code>slim.before</code> hook.  Extracting the language from the URI is important as it will allow us to use the same set of routes for all of the languages.  We will create a simple custom view template that will use a translator service to perform the lookups we will need to display the multilingual content.  The translations will be stored in language resource files.  We will also subclass the Slim application class to ensure <code>urlFor()</code> is still available and working for us.  By the end of this post we will have a full multilingual application that will be able to responsd to the following URI's:</p>

<pre><code class="bash">
http://127.0.0.1/
http://127.0.0.1/en
http://127.0.0.1/de
http://127.0.0.1/ru
http://127.0.0.1/about
http://127.0.0.1/en/about
http://127.0.0.1/de/about
http://127.0.0.1/ru/about
http://127.0.0.1/login
http://127.0.0.1/en/login
http://127.0.0.1/de/login
http://127.0.0.1/ru/login
</code></pre>

<h2>Spoiler Alert</h2>

<p>If you want to skip my ramblings below you can run the following commands to have the application up and running in about 10 seconds, depending on typing speed.  This assumes you are using PHP 5.4+ with the embedded webserver.  If not it will take you longer.</p>

<pre><code class="bash">
git clone git://github.com/briannesbitt/Slim-Multilingual.git
cd Slim-Multilingual
curl -s http://getcomposer.org/installer | php
php composer.phar install
php -S 127.0.0.1:80
</code></pre>

<p>The project uses composer to install the latest <code>1.6.*</code> version of Slim and also to generate an autoload for all of the classes in the <code>app/lib/</code> directory via the composer classmap feature.</p>

<h2>Parsing the current language and common routes</h2>

<p>As you can see from above some of the URIs implicitly specify the language while others do not.  When the language isn't specified and a request for the index is made, we first use the <code>ACCEPT_LANGUAGE</code> header to try and guess the appropriate language from our sites available languages.  If a suitable language is not matched we will fallback to the site default and go ahead and render the page.  You could put a language chooser page in place if you wanted to rather than using the default language.  Our application will simply render the requested page using english but also show a language switch option which will maintain the current page context when switching.</p>

<p>Lets start this by first showing the common route for the homepage.  We want the following route to match against URI's #1, #2, #3 and #4 from above.</p>

<pre><code class="php">
$app->get('/', function () use ($app) {
   $app->render('home.php');
});
</code></pre>

<p>The only way to do that (without using optional route parameters due to their limitations) is to parse and extract the language from the URI.  This must happen before Slim performs its routing logic so the proper matches take place.  For this we will use a <code>slim.before</code> <a href="http://www.slimframework.com/documentation/stable#hooks-default">hook</a>.  Slim will perform its route matching based on the URI in <code>$env['PATH_INFO']</code> where <code>$env = $app->environment()</code>.  So as part of the <code>slim.before</code> hook we simply loop through the <code>$availableLangs</code> and see if the URI begins with <code>/lang/</code>.  If so we can <code>substr()</code> the <code>$env['PATH_INFO']</code> to extract the language and write the shorter URI back to the <code>$env['PATH_INFO']</code> variable.  If we are quiet enough then Slim won't know the difference and it will go ahead and match routes against the modified URI.</p>

<pre><code class="php">
$pathInfo = $env['PATH_INFO'] . (substr($env['PATH_INFO'], -1) !== '/' ? '/' : '');

// extract lang from PATH_INFO
foreach($availableLangs as $availableLang) {
   $match = '/'.$availableLang;
   if (strpos($pathInfo, $match.'/') === 0) {
      $lang = $availableLang;
      $env['PATH_INFO'] = substr($env['PATH_INFO'], strlen($match));

      if (strlen($env['PATH_INFO']) == 0) {
         $env['PATH_INFO'] = '/';
      }
   }
}
</code></pre>

<p>The first line of code from above is necesssary to match against a URI like <code>/en</code>.  Our attempted match string will be <code>/en/</code> so we need to append the trailing <code>/</code>.  If we only match against <code>/en</code> then we could improperly intercept other routes like <code>/entertain</code> which would be a request for the entertain page without a language specified.  The full <code>slim.before</code> hook can be seen at <a href="https://github.com/briannesbitt/Slim-Multilingual/blob/master/app/hooks.php">https://github.com/briannesbitt/Slim-Multilingual/blob/master/app/hooks.php</a></p>

<p>Once we have the <code>$lang</code> determined we can set it in our view at the end of the hook as the following code shows.  We also initialize some variables that will always be available to the view. The custom view will be examined in a bit.</p>

<pre><code class="php">
$app->view()->setLang($lang);
$app->view()->setAvailableLangs($availableLangs);
$app->view()->setPathInfo($env['PATH_INFO']);
</code></pre>

<p>With the URI modifications completed Slim will go ahead and perform its matching as usual, not knowing anything about the language that was once there.  This allows us to create our 3 page application with the following 4 routes.</p>

<pre><code class="php">
&lt;?
$app->get('/', function () use ($app) {
    $app->render('home.php');
})->name('home');

$app->get('/about', function () use ($app) {
    $app->render('about.php');
})->name('about');

$app->get('/login', function () use ($app) {
    $app->render('login.php');
})->name('login');

$app->post('/login', function () use ($app) {
    $app->render('login.php', array('error' => $app->view()->tr('login-error-dne', array('email' => $app->request()->post('email')))));
})->name('loginPost');
</code></pre>

<p>You can see the login page requires 2 routes, one for displaying the form and a second to receive the form POSTing.</p>

<h2>Custom view with Master Template</h2>

<p>The templating provided with Slim is pretty basic (there is a <a href="https://github.com/codeguy/Slim-Extras">Slim-Extras</a> repo that integrates other templating engines into Slim).  To prevent the duplication of html the typical Slim template will look like this:

<pre><code class="php">
&lt;?
include 'header.php';
&lt;p>This is my content.&lt;/p>
include 'footer.php';
</code></pre>

<p>I would suggest using a Slim-Extras template but to keep this application simple and from having any external dependencies we will turn the tables.  With no change to your routes and very little code you can add master template functionality to your custom template and thus preventing the duplication of including the header and footer on each page.</p>

<p>First we create a custom view class <code>MasterView</code> that extends <code>Slim_View</code>.  We setup a constructor that accepts a master template parameter and stores it.</p>

<p>Now to complete the view code we just need to override the <code>render()</code> function.  If the <code>masterTemplate</code> was set then <code>render()</code> swaps the template with the master template and sets up a <code>$childView</code> variable so the master template can <code>require</code> it.  Here is the full <code>MasterView</code> class in all of its 15 lines of glory.</p>

<pre><code class="php">
&lt;?
class MasterView extends Slim_View {
    private $masterTemplate;

    public function __construct($masterTemplate) {
        parent::__construct();
        $this->masterTemplate = $masterTemplate;
    }

    public function render($template) {
        $this->setData('childView', $template);
        $template = $this->masterTemplate;
        return parent::render($template);
    }
}
</code></pre>

<h2>The Translator and the MultilingualView</h2>

<p>Is it just me or does that sound like a cheesy horror movie name?  Anyway, of course our view needs to provide translation of content for us.  This I did using a translator service that gets injected into the <code>MultilingualView</code> constructor.  The view then provides a simple helper <code>tr()</code> to make it easier for our templates to access.  With a simple <code>str_replace()</code> the translator provides a way to inject variables into the translated content.  So you can setup error messages like <code>Sorry, there is no user with an email of "{{email}}".</code></p>

<p>As we saw earlier, the <code>slim.before</code> hook is where the language is determined.  At the end of that hook the langauge, available languages and path info is set.  These setter functions simply use the parent <code>setData()</code> function to create variables that will exist in the context of the view.  So in the view if you want to know the current language you can just do <code>$lang</code> or looping through the available lanagues can be done like <code>foreach($availableLangs as $availableLang)</code>.  This also makes the helper methods to perform the translation easier to access as the current language is known and doesn't have to be passed in, <code>$this->tr('home-content')</code>.</p>

<p>The language resoure files follow the naming convention of <code>lang.en.php</code> where <code>en</code> is the language code.  These are simple PHP files that use an associative array to setup the translations.  Since it is just PHP you can require other files, load them from a <a href="http://redis.io">datastore</a> or use <a href="http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc">HEREDOC</a> for longer paragraphs.  If a translation is requested for a key that does not exist a blank string is returned and an error is written to the Slim application log.  This could be changed to throw an exception to ensure its not missed during testing.  I also auto require a <code>lang.common.php</code> file that has common terms.  A good example for using this is the language chooser.  You don't display <code>German</code> when on the english site.  You always dipslay <code>Deutsch</code> for all languages so someone looking for the German version will be able to find it.</p>

<p>Sometimes its easier to view all of the content in the context of the page and html rather than in the language resource file. Here you have a few choices.  Say you have an about page that is broken into 4 &lt;p&gt; tags.  You can split the p tags over a few language resource keys, use a HEREDOC and put the html in a single resource key or include a language specific sub template.  Here are the implementation options for the <code>about.php</code> view file:</p>

<pre><code class="php">
<p>&lt;?php echo $this->tr('about-p1')?></p>
<p>&lt;?php echo $this->tr('about-p2')?></p>
<p>&lt;?php echo $this->tr('about-p3')?></p>
<p>&lt;?php echo $this->tr('about-p4')?></p>
</code></pre>

<pre><code class="php">
&lt;?php echo $this->tr('about-content')?>
</code></pre>

<pre><code class="php">
&lt;?php require 'about_'.$lang.'.php'?>
</code></pre>

<p>I think for this example I would choose the 3rd option.  Anything more complicated would require mixins, more child templates etc. etc. and I would really start to lean to looking at the many templating engines out there.  What I do like about this one is that its really simple, easy to understand and flexible since it is just PHP.</p>

<h2>Ensuring $app->urlFor() still works</h2>

<p>This is actually much easier that it seems.  You can subclass the Slim application and override the <code>urlFor()</code> function.  It just needs to prepend <code>/lang</code> (lang being the current language) to the url returned by the parent <code>urlFor()</code>.  The full 6 line class is shown here:</p>

<pre><code class="php">
&lt;?
class MultilingualSlim extends Slim {
    public function urlFor( $name, $params = array() ) {
        return sprintf('/%s%s', $this->view()->getLang(), parent::urlFor($name, $params));
    }
}
</code></pre>

<p>Follow this up by changing your application creation from <code>$app = new Slim(array('templates.path' => './app/views/'));</code> to <code>$app = new MultilingualSlim(array('templates.path' => './app/views/'));</code> and your done.</p>

<p>I'll also mention that rather than setting the custom view when the application is created, I used the <code>$app->view()</code> function to pass in an instance of the <code>MultilingualView</code> class.  This allowed me to pass some arguments when constructing the view class.</p>

<h2>Wrap up</h2>

<p>Thats it!  This is a first pass at creating a simple multilingual site using Slim.  There isn't much code here so I think its safe to say someone could to take a look and be up and running in a few minutes.  Oh and to try out the repo, use composer to install Slim and setup the application autoload you will be up and running in no time!  Jump back to the Spoiler Alert at the beginning to see the commands necessary to try this out.</p>

<h2>Links</h2>

<p>
   <a href="http://slimframework.com">http://slimframework.com</a><br/>
   <a href="http://github.com/briannesbitt/Slim-Multilingual">http://github.com/briannesbitt/Slim-Multilingual</a><br/>
   <a href="http://help.slimframework.com/discussions/questions/244-multilingual-site-with-slim">http://help.slimframework.com/discussions/questions/244-multilingual-site-with-slim</a>
</p>

<br/>]]></description>
   </item>
      <item>
      <title>Slim wildcard routes improved</title>
      <link>http://nesbot.com/2012/7/3/slim-wildcard-routes-improved</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Tue, 03 Jul 12 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2012/7/3/slim-wildcard-routes-improved</guid>
      <description><![CDATA[
<p class="quote">This is a follow up to <a href="http://nesbot.com/2012/6/18/slim-wildcard-routes-via-route-middleware">Slim wildcard routes via route middleware</a>... you may want to go and read that first.</p>
<p>The method used in the previous post was sufficient to get the job done but was not ideal as the resulting array was stored in the slim <code>environment</code>.  At the time it was the "best" spot to store it without introducing a new dependency.  Here is what I said in the previous post:</p>

<p class="quote">... this could be better if the route middleware was able to inject the new array back into the parameters rather than storing it into the environment. For now this is an easy solution to implement and is reuseable until the feature is added to the framework itself.</p>

<p>With the release of <a href="http://www.slimframework.com/read/version-164">Slim 1.6.4</a> the feature to <code>let the Slim_Route inject custom parameter values</code> was added.  We can use this to improve our wildcard routes example with a few simple changes.  Instead of using the <code>environment</code>, our array will be injected back into the parameters being passed directly to the route.  As a reminder the example URIs we want to parse into the array are:</p>

<pre><code class="bash">
http://hostname/api/getitems/seafood/fruit/meat
http://hostname/api/getitems/seafood
http://hostname/api/getitems/seafood/fruit/apples/bananas/chocolate
</code></pre>

<p>Here is the diff with the changes to our route middleware:</p>

<pre><code class="php">
-$parseWildcardToArray = function ($param_name) use ($app) &#123;
-   return function ($req, $res, $route) use ($param_name, $app) &#123;
+$parseWildcardToArray = function ($param_name) {
+   return function ($req, $res, $route) use ($param_name) {

-      $env = $app->environment();
-      $params = $route->getParams();
-
-      $env[$param_name.'_array'] = array();
-
-      //Is there a useful url parameter?
-      if (!isset($params[$param_name]))
-      {
-         return;
-      }
-
-      $val = $params[$param_name];
+      $val = $route->getParam($param_name);

       //Handle  /api/getitems/seafood//fruit////meat
       if (strpos($val, '//') !== false)
       {
          $val = preg_replace("#//+#", "/", $val);
       }

       //Remove the last slash
       if (substr($val, -1) === '/')
       {
          $val = substr($val, 0, strlen($val) - 1);
       }

       //explode or create array depending if there are 1 or many parameters
       if (strpos($val, '/') !== false)
       {
          $values = explode('/', $val);
       }
       else
       {
          $values = array($val);
       }

-      $env[$param_name.'_array'] = $values;
+      $route->setParam($param_name, $values);
    };
 };
</code></pre>

<p>First we removed the <code>use</code> of <code>$app</code> for the closure since we don't need it anymore.  Next we simplified the code as we were able to remove lines 6-17.  We no longer need to access the environment.  The check for a value can be removed since we are only getting the specific value and our route condition <code>/.+/</code> ensures there is something in there.  Previously we were getting all route parameters as an associative array so we had a check to ensure the key existed and was set.  All of that is replaced by a simple <code>getParam()</code> call.  The final difference is how the modification takes place.  We now write it back into the route parameters directly rather than to the environment.</p>

<p>Here is our new route middleware:</p>

<pre><code class="php">
$parseWildcardToArray = function ($param_name) {
   return function ($req, $res, $route) use ($param_name) {

      $val = $route->getParam($param_name);

      //Handle  /api/getitems/seafood//fruit////meat
      if (strpos($val, '//') !== false)
      {
         $val = preg_replace("#//+#", "/", $val);
      }

      //Remove the last slash
      if (substr($val, -1) === '/')
      {
         $val = substr($val, 0, strlen($val) - 1);
      }

      //explode or create array depending if there are 1 or many parameters
      if (strpos($val, '/') !== false)
      {
         $values = explode('/', $val);
      }
      else
      {
         $values = array($val);
      }

      $route->setParam($param_name, $values);
   };
};
</code></pre>

<p>You can see that our route is a little easier as the parsed array is now just in the parameter.</p>

<pre><code class="php">
$app->get('/api/getitems/:items', $parseWildcardToArray('items'), function ($items) {
    var_dump($items);
})->conditions(array('items' => '.+'));
</code></pre>

<p>As before, this just prints the following arrays for the three urls from above:</p>

<pre><code class="bash">
array(3) { [0]=> string(7) "seafood" [1]=> string(5) "fruit" [2]=> string(4) "meat" }
array(1) { [0]=> string(7) "seafood" }
array(5) { [0]=> string(7) "seafood" [1]=> string(5) "fruit" [2]=> string(6) "apples" [3]=> string(7) "bananas" [4]=> string(9) "chocolate" }
</code></pre>

   <p class="quote">Read the last follow up to see it integrated into Slim in conjuction with the 1.6.5 release... <a href="http://nesbot.com/2012/8/3/slim-wildcard-routes-last-but-not-least">Slim wildcard routes : Last but not least</a></p>
]]></description>
   </item>
      <item>
      <title>Slim wildcard routes : Last but not least</title>
      <link>http://nesbot.com/2012/8/3/slim-wildcard-routes-last-but-not-least</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Fri, 03 Aug 12 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2012/8/3/slim-wildcard-routes-last-but-not-least</guid>
      <description><![CDATA[
<p class="quote">This is a follow up to <a href="http://nesbot.com/2012/7/3/slim-wildcard-routes-improved">Slim wildcard routes improved</a>... you may want to go and read that first.</p>
<p>With the release of <a href="http://www.slimframework.com/read/version-165">Slim 1.6.5</a>, route wildcard parameters are now officially part of the framework.  Lets take at look at our past example and improve it again to use the baked in feature.  As a reminder the example URIs we want to parse into the array are:</p>

<pre><code class="bash">
http://hostname/api/getitems/seafood/fruit/meat
http://hostname/api/getitems/seafood
http://hostname/api/getitems/seafood/fruit/apples/bananas/chocolate
</code></pre>

<p>To indicate a route wildcard parameter we simply add a <code>+</code> after the name of the parameter, <code>/api/getitems/:items+</code>.  We can now specify our route as follows:</p>

<pre><code class="php">
$app->get('/api/getitems/:items+', function ($items) {
    var_dump($items);
});
</code></pre>

<p>The output is printed as before for the three urls from above:</p>

<pre><code class="bash">
array(3) { [0]=> string(7) "seafood" [1]=> string(5) "fruit" [2]=> string(4) "meat" }
array(1) { [0]=> string(7) "seafood" }
array(5) { [0]=> string(7) "seafood" [1]=> string(5) "fruit" [2]=> string(6) "apples" [3]=> string(7) "bananas" [4]=> string(9) "chocolate" }
</code></pre>

<p>I'll finish off with something you might be wondering.  You can specify additional parameters after the wildcard.  The only gotcha here is that they can't be optional or the wildcard will gobble them all up and always leave the optional as the default value.  I would describe this as expected behaviour.</p>

<pre><code class="php">
$app->get('/api/getitems/:items+/:name', function ($items, $name) {
    var_dump($items);
    var_dump($name);
});
</code></pre>

<p>The above route will not match <code>http://hostname/api/getitems/fruit</code> but will match <code>http://hostname/api/getitems/fruit/brian</code> and <code>http://hostname/api/getitems/seafood/fruit/meat/brian</code>.</p>]]></description>
   </item>
      <item>
      <title>Introducing Carbon : A simple API extension for DateTime with PHP 5.3+</title>
      <link>http://nesbot.com/2012/10/29/introducing-carbon-simple-api-for-datetime-php</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Mon, 29 Oct 12 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2012/10/29/introducing-carbon-simple-api-for-datetime-php</guid>
      <description><![CDATA[
<p>Unofficially released last month, <a href="https://github.com/briannesbitt/Carbon">Carbon</a> is <code>A simple API extension for DateTime with PHP 5.3+</code>. Code examples are worth a thousand words so lets start with this:</p>

<pre><code class="php">
printf("Right now is %s", Carbon::now()->toDateTimeString());
printf("Right now in Vancouver is %s", Carbon::now('America/Vancouver'));  //implicit __toString()
$tomorrow = Carbon::now()->addDay();
$lastWeek = Carbon::now()->subWeek();
$nextSummerOlympics = Carbon::createFromDate(2012)->addYears(4);

$officialDate = Carbon::now()->toRFC2822String();

$howOldAmI = Carbon::createFromDate(1975, 5, 21)->age;

$noonTodayLondonTime = Carbon::createFromTime(12, 0, 0, 'Europe/London');

$worldWillEnd = Carbon::createFromDate(2012, 12, 21, 'GMT');

// comparisons are always done in UTC
if (Carbon::now()->gte($worldWillEnd)) {
   die();
}

if (Carbon::now()->isWeekend()) {
   echo 'Party!';
}

echo Carbon::now()->subMinutes(2)->diffForHumans(); // '2 minutes ago'

// ... but also does 'from now', 'after' and 'before'
// rolling up to seconds, minutes, hours, days, months, years

$daysSinceEpoch = Carbon::createFromTimeStamp(0)->diffInDays();
</code></pre>

<p>For full installation instructions, documentation and code examples you should visit the repo <a href="https://github.com/briannesbitt/Carbon">https://github.com/briannesbitt/Carbon</a> but with <a href="http://getcomposer.org/">composer</a> (or without, but why would you??) you should be up and running in seconds.  If you want to see the project history, its tracked <a href="https://github.com/briannesbitt/Carbon/blob/master/history.md">here</a>. Feedback is welcomed.</p>

<p>I hate reading a readme.md file that has code errors and/or sample output that is incorrect. I tried something new with this project and wrote a quick <a href="https://github.com/briannesbitt/Carbon/blob/master/readme.php">readme parser</a> that can lint sample source code or execute and inject the actual result into a generated readme.  I'll create another post about this, but for now if you want to read more you can continue reading this in the <a href="https://github.com/briannesbitt/Carbon#about-contributing">Contributing</a> section of the project readme.</p>

<h2>What's up next?</h2>

<p>There have been a few feature requests already submitted.  A few users have asked for an immutable implementation.  There are no definite plans, but I think a copy on write implementation would be pretty simple to layer on top.  This might get in there in the future if it gets mentioned a few more times.  The other feature, which was targeted at testability, was an implemention of the <a href="https://github.com/bebanjo/delorean">Delorean time travel API</a> that allows the mocking of <code>Time.now</code> in Ruby.  We went <a href="https://github.com/briannesbitt/Carbon/pull/1">back and forth</a> a bit on the implementation details and ended up closing it for lack of a satisfactory solution that wasn't confusing in the end.  The idea is a good one and some implementation to allow easy mocking of <code>Carbon::now()</code> will get added in the future.  As already mentioned feedback, ideas and code submissions are welcomed.</p>

<h2>Why the name Carbon?</h2>

<p>Read about <a href="http://en.wikipedia.org/wiki/Radiocarbon_dating">Carbon Dating</a>.</p>

<h2>Why require PHP 5.3?</h2>

<p>And finally just a quick note on the PHP 5.3 requirement. The implementation requires PHP 5.3+ since it makes use of <a href="http://www.php.net/manual/en/datetime.add.php">DateTime::add</a> which uses the <a href="http://www.php.net/manual/en/class.dateinterval.php">DateInterval</a> class and those were only introduced in 5.3 simple as that.  Its also more than 3 years old so I doubt this is much of an issue for anyone.</p>]]></description>
   </item>
      <item>
      <title>Lazy loading Slim controllers using Pimple</title>
      <link>http://nesbot.com/2012/11/5/lazy-loading-slim-controllers-using-pimple</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Mon, 05 Nov 12 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2012/11/5/lazy-loading-slim-controllers-using-pimple</guid>
      <description><![CDATA[
<p>A popular question on the <a href="http://help.slimframework.com/discussions">Slim discussion forum</a> is how to mix controllers with Slim routes.  There are a few threads discussing several implementations but all are very similar.  The other concern users have is the performance hit of creating each of the controller objects and having all routes instantiated on every request.  I have responded that most of these concerns I would categorize as early over optimizations.  Not to mention there are improvements in Slim that will be happening to increase performance internally.  Currently, on every request, all routes are matched against the request, using a regex, and a list of the passing ones are returned and the first is used to serve up the response.  The main reason this is done is to support the <a href="http://docs.slimframework.com/pages/routing-helper-methods/#pass"><code>$app->pass()</code></a> feature which, when called, will skip to the next matching route.  The optimization will execute the first matching route immediately and only continue with the others if <code>pass()</code> is used.  The first reaction for most is to reduce the number of routes added per request based on the URI, which works but limits the usefulness of <code>urlFor()</code> which we'll cover next.</p>

<h2>urlFor()</h2>

<p>The <a href="http://docs.slimframework.com/pages/routing-helper-methods/#url_for"><code>urlFor()</code></a> lets you dynamically create URLs for a named rotue so that, were a route pattern to change, your URLs would update automatically without breaking your application.  This only works if all of the applications routes are known (added) to the Slim application.  A URL can't be constructed for an unknown route.</p>

<h2>Common first attempt</h2>

<p>There are many implemenations that attempt to solve this.  The most common "non-magical" attempt at solving some of these issues are to optionally require a routes file per section of the site based on the first portion of the requested path.  The implementation is typically added to a hook which runs before the routing sequence and looks something like this:</p>

<pre><code class="php">
$app = new Slim();

$app->hook("slim.before.router",function() use ($app){
    if (strpos($app->request()->getPathInfo(), "/user") === 0) {
        require_once('user/routes.php');
    } elseif (strpos($app->request()->getPathInfo(), "/post") === 0) {
        require_once('post/routes.php');
    } elseif (strpos($app->request()->getPathInfo(), "/admin") === 0) {
        require_once('admin/routes.php');
    } else {
        require_once('routes.php');  // default routes
    }
});

$app->run();
</code></pre>

<p>The <code>user/routes.php</code> file would contain all of the user routes with a callable that is either a typical closure, or if a controller class is to be used one might create a <code>UserController</code> class and attach member functions as the route callables <code>$userController = new UserController($app); $app->get('/user/:id', array($userController, 'index'))->name('userFind');</code>.  This all works fine, but renders <code>urlFor()</code> useless.</p>

<h2>Delayed Creation with no magic</h2>

<p>If we could delay the potentially expensive creation of the controllers we could still add all the routes and use <code>urlFor()</code>.  We can delay the controller creation using various PHP magic techniques, but lets try and avoid those and stick to a simple solution.</p>

<pre><code class="php">
$app->get('/user/:id', function ($id) {
   if ($GLOBALS['UserController'] == null) {
      $GLOBALS['UserController'] = new UserController();
   }

   $GLOBALS['UserController']->find($id);
})->name('user');
</code></pre>

<p>Did you catch why this works and successfully delays the creation of the UserController?  We don't need the controller instance to define the callable as before.  Instead we implement a very simple closure that then calls the UserController. This is a rudimentary implementation.  We are storing a single instance globally and accessing it everywhere, not very DRY and not easy to test.</p>

<pre><code class="php">
class UserController
{
   private $instance;

   public static function getInstance() {
      if ($this->instance == null) {
         $this->instance = new UserController();
      }

      return $this->instance;
   }
}

$app->get('/user/:id', function ($id) {
   UserController::getInstance()->find($id);
})->name('user');
</code></pre>

<p>This is a bit better as we have now centralized the object creation making it more DRY.  The code is still highly coupled and not easy to test. Lets move on to a better solution.</p>

<h2>Pimple</h2>

<p><a href="http://pimple.sensiolabs.org/">Pimple</a> is a simple dependency injection container for PHP 5.3+.  Moving along I'll assume you have read about it.</p>

<h2>Lazy loading using Pimple</h2>

<p>We can now build on our previous ideas but now we use Pimple to lazy load our controllers, and other expensive objects, while still adding all routes to the application so <code>urlFor()</code> can be used.</p>

<p>We use Pimple's <code>share()</code> feature to associate each controller object with a closure that is responsible for creating it, when needed (ie. first read access).  Lets get to our new solution using a simple site as an example.</p>

<p>As usual, we'll manage our dependencies using <a href="http://getcomposer.org">composer</a>.</p>

composer.json

<pre><code class="javascript">
{
   "require": {
      "slim/slim": "2.*",
      "pimple/pimple": "*"
   },
   "minimum-stability": "dev"
}
</code></pre>

index.php

<pre><code class="php">
&lt;?
require 'vendor/autoload.php';
require 'controllers.php';
require 'services.php';
require 'db.php';

$app = new \Slim\Slim();

$pimple = new Pimple();
$pimple['app'] = $app;

$pimple['UserController'] = $pimple->share(function ($pimple) {
    echo '<hr/>Created UserController<hr/>';
    return new UserController($pimple);
});

$pimple['UserService'] = $pimple->share(function ($pimple) {
    echo '<hr/>Created UserService<hr/>';
    return new UserService($pimple);
});

$pimple['db'] = $pimple->share(function ($pimple) {
    echo '<hr/>Created Db<hr/>';
    return new Db($pimple);
});

$app->get('/', function () use ($pimple) {
   //$pimple['app']->render('index.php', array('userCount' => $pimple['UserService']->count()));
   echo 'Root.  Current User count is ' . $pimple['UserService']->count();
});

$app->get('/contact', function () use ($pimple) {
   //$pimple['app']->render('contact.php');
   printf('Simple contact page.  Link to <a href="%s">User 11</a>', $pimple['app']->urlFor('user', array('id' => 11)));
});

$app->get('/user/:id', function ($id) use ($pimple) {
   $pimple['UserController']->find($id);
})->name('user');

$app->get('/users', function () use ($pimple) {
   $pimple['UserController']->all();
})->name('users');

$app->run();
</code></pre>

controllers.php

<pre><code class="php">
&lt;?
abstract class Controller
{
   protected $app;
   protected $service;

   public function __construct(Pimple $di) {
      $this->app = $di['app'];
      $this->init($di);
   }

   public abstract function init(Pimple $di);
}

class UserController extends Controller
{
   public function init(Pimple $di) {
      $this->service = $di['UserService'];
   }

   public function find($id) {
      //$this->app->render('user.php', array('user' => $this->service->find($id)));
      echo 'Found the user with id = ' . $id . '<br/>';
      var_dump($this->service->find($id));
   }

   public function all() {
      //$this->app->render('users.php', array('users' => $this->service->all()));
      echo 'Found all users.<br/>';
      var_dump($this->service->all());
   }
}
</code></pre>

services.php

<pre><code class="php">
&lt;?
class UserService
{
   protected $db;
   protected $app;

   public function __construct(Pimple $di) {
      $this->db = $di['db'];
      $this->app = $di['app'];
   }

   public function find($id) {
      return $this->db->findUser($id);
   }

   public function all() {
      return $this->db->allUsers();
   }

   public function count() {
      return $this->db->countUser();
   }
}
</code></pre>

db.php

<pre><code class="php">
&lt;?

/***** replace with real db access *****/

class Db
{
   public function __construct(Pimple $di) {
   }

   private function createUser($id) {
      $user = new stdClass();
      $user->id = $id;
      return $user;
   }

   public function findUser($id) {
      return $this->createUser($id);
   }

   public function allUsers() {
      return array($this->createUser(1), $this->createUser(2), $this->createUser(3));
   }

   public function countUser() {
      return rand(1000000,2000000);
   }
}
</code></pre>

<p>The UserController is not created until it is accessed via <code>$pimple['UserController']</code>.  This doesn't happen until the closure for either the <code>/user/:id</code> or <code>/user/all</code> routes are actually executed.  Their route callables are simple wrappers to the controller member function.  If we had used our previous example of <code>$app->get('/user/:id', array($pimple['UserController'], 'find'))->name('user');</code> then the controller would have been created when the route was added to Slim rather than lazily when it was actually executed.  This is a pretty simple implementation that doesn't use any PHP magic and therefore should be simple to follow.  Its also very apparent that your application is pretty easy to test as using Pimple makes it easy to mock all of the various layers.</p>

<p>Now we can add all of our routes and save the expensive object creation until its actually used.  This allows us to use <code>$app->urlFor('user', array('id' => 11))</code> to provide a URL like <code>/user/11</code> as you can see on the contact page from above.  If ever that URL was to change we don't need to change our code everywhere.</p>

<p>You will also notice that the index page shows a count of all of the registered users.  This is done with an instance of the UserService and does not need an instance of the controller to be created.  Finally note that the simple contact page can be rendered quickly and avoids the controller, service or db object creations.</p>

<p>I have commented out the tmeplate renders so you can at least see something meaningful in the responses.</p>]]></description>
   </item>
      <item>
      <title>Updated ContextSensitiveLoginLogout example to Slim 2.x</title>
      <link>http://nesbot.com/2012/12/6/updated-ContextSensitiveLoginLogout-example-to-slim-2</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Thu, 06 Dec 12 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2012/12/6/updated-ContextSensitiveLoginLogout-example-to-slim-2</guid>
      <description><![CDATA[
<p>A question, awhile back, on the <a href="http://help.slimframework.com/discussions/questions/341-loginlogout-with-redirect">Slim discussion forum</a> asked how to create a login/logout workflow with a redirect to the originally requested page on login.  I had created an example to show this using Slim 1.6.x.  Recently I updated the example to work with the 2.x version of Slim.  Lets review the changes that were applied to make this happen.</p>

<p>The example can be seen here <a href="https://github.com/briannesbitt/Slim-ContextSensitiveLoginLogout">https://github.com/briannesbitt/Slim-ContextSensitiveLoginLogout</a></p>

<h2>Namespaces</h2>

<p>The Slim 2.x branch added <a href="http://www.phptherightway.com/#namespaces">namespaces</a>.  This means we need to update our Slim references with the equivalent namespaced version.  There are two ways we can do this.  First lets see how it was done in our example.  The following is the <a href="https://github.com/briannesbitt/Slim-ContextSensitiveLoginLogout/commit/a06f78fffaecf57c39a6e249ac48651dce170643#index.php">diff listing for our commit</a> on the index.php file.</p>

<pre><code class="php">
&lt;?php
require 'vendor/autoload.php';

- $app = new Slim();
+ $app = new \Slim\Slim();

- $app->add(new Slim_Middleware_SessionCookie(array('secret' => 'myappsecret')));
+ $app->add(new \Slim\Middleware\SessionCookie(array('secret' => 'myappsecret')));
</code></pre>

<p>What you see above are the only code changes that were necessary to make this work with Slim 2.x.  The other changes in the commit were to the readme and composer.json file.</p>

<p>The second method we could have implemented is to introduce the usage of the <a href="http://php.net/manual/en/language.namespaces.importing.php">PHP keyword use</a>.  Importing the namespaces with the <code>use</code> keyword at the top of the file means we don't have to supply the full namespaced class when actually using and referencing the class.  Lets see how that would have been done.</p>

<pre><code class="php">
&lt;?php
require 'vendor/autoload.php';

+ use Slim\Slim;
+ use Slim\Middleware\SessionCookie;

$app = new Slim();

- $app->add(new Slim_Middleware_SessionCookie(array('secret' => 'myappsecret')));
+ $app->add(new SessionCookie(array('secret' => 'myappsecret')));
</code></pre>

<p>Adding the <code>use</code> imports at the top prevents us from having to add <code>\Slim\</code> in front of all of the Slim class references.  Our example is simple so in this instance, I think either method is fine, but in a longer example you can see how using <code>use</code> might be the better option, however making the code less explicit.</p>

<p>This is a simple example so as we discussed the code changes were very minimal. You can refer to the following sites to see what else changed and further tips on upgrading:</p>

<p>
   <a href="http://slimframework.com/news/moving-forward">http://slimframework.com/news/moving-forward</a><br/>
   <a href="http://slimframework.com/news/version-2">http://slimframework.com/news/version-2</a><br/>
   <a href="http://help.slimframework.com/kb/upgrading/upgrading-to-slim-2">http://help.slimframework.com/kb/upgrading/upgrading-to-slim-2</a><br/>
</p>]]></description>
   </item>
      <item>
      <title>This blog trimmed the fat - Now powered by Slim 2</title>
      <link>http://nesbot.com/2013/1/11/this-blog-trimmed-the-fat-now-powered-by-slim-2</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Fri, 11 Jan 13 12:00:00 -0500</pubDate>
      <guid>http://nesbot.com/2013/1/11/this-blog-trimmed-the-fat-now-powered-by-slim-2</guid>
      <description><![CDATA[
<p>Today is the day!  I have been meaning to blog about this for some time now.  If you looked at the repo history you would see that this diet actually took place a few months ago. The <a href="http://www.slimframework.com">Slim Framework</a> released version 2.0 on <a href="http://www.slimframework.com/news/version-2">September 13</a> last year and I was up and running a few days later.  Today I will talk about it.</p>

<h2>Repo</h2>

<p>The repo is located at <a href="https://github.com/briannesbitt/nesbot.com">https://github.com/briannesbitt/nesbot.com</a>.  The latest and greatest is in master... there is no fancy branching model and there are no plans to use one.</p>

<h2>Again?</h2>

<p>Yes this will be the third rewrite of my blog.  As you can see at the bottom of the readme the previous versions were done using the Playframework 1.2.3 (https://github.com/briannesbitt/v1.nesbot.com) and Playframework BETA 2.0 (https://github.com/briannesbitt/v2.nesbot.com).  A blog is a simple and well understood application, which makes it a good first project when picking up a new language or framework.  This time its a new framework as I have been using PHP on and off since the very early 3 days.</p>

<h2>Running</h2>

<p>If you have PHP 5.4+ installed and have the composer.phar you can be up and running in 10 seconds +/- 5 seconds for slower typers or copy & pasters.</p>

<pre><code class="bash">
git clone git://github.com/briannesbitt/nesbot.com.git
cd nesbot.com
curl -s http://getcomposer.org/installer | php
php composer.phar update
touch env.local
cd public
php -S 127.0.0.1:80
</code></pre>

<h2>Local mode</h2>

<p>The site begins at <code>public/index.php</code> which only contains a require statement for the <code>app.php</code>. After the composer require the script will attempt to determine the desired mode of the application.  First it checks for a server variable and if not found it looks for a particular file.  On live the server variable is used so the disk hit can be avoided.  It is easily specified using <code>fastcgi_param MODE live;</code> in the nginx <code>location</code> configuration.  When developing locally I use the built-in dev server in PHP 5.4+ so the file is used instead.  The configuration for local mode in the <code>app.php</code> is very similar to the live config but does some extra asset bundling by executing the <code>bundle.php</code> script.  This script will generate the posts, compile/combine/compress the less files, minify/combine the js files.  This happens in local mode on each page hit which is handy when you are writing posts and want to refresh to read them and is more than fast enough you don't notice any lag in page render.  This only happens on live when deploying which we will walk through later.</p>

<h2>Posts</h2>

<p>Posts are kept in simple PHP view files.  The files use a name format of <code>yyyy-m-d-slug.php</code> and are stored in the <code>views/posts/</code> directory.  The title of the post is read from the first line of the view in a format like <code>&lt;?/*Post title*/?></code>.  The site's datastore is a dynamically generated PHP file, <code>posts.php</code>, with an array of post data.  The file is generated by reading all of the post view files, parsing the date, slug and title, sorting them by date and finally writing out the sorted array and necessary code.  Adding a post in local mode is as simple as creating a new view file with a valid name, add the title and start typing.</p>

<p>The final piece of generated code creates the <code>Posts</code> object, adds each <code>Post</code> and returns it.</p>

<pre><code class="php">
$postData = array();

$postData[] = new Post('A carpenter\'s house is always the last to get the attention it deserves', "carpenters-house-last-to-get-attention", \Carbon\Carbon::createFromTimestamp(1315411200));
...
$postData[] = new Post('Updated ContextSensitiveLoginLogout example to Slim 2.x', "updated-ContextSensitiveLoginLogout-example-to-slim-2", \Carbon\Carbon::createFromTimestamp(1354813200));
$postData[] = new Post('This blog trimmed the fat - Now powered by Slim 2', "this-blog-trimmed-the-fat-now-powered-by-slim-2", \Carbon\Carbon::createFromTimestamp(1357923600));

$posts = new Posts();
foreach($postData as $post)
{
   $posts->add($post);
}

return $posts;
</code></pre>

   <p>The Post object consists of a <code>title</code>, <code>slug</code> and a <code>posted</code> object of type <a href="http://nesbot.com/2012/10/29/introducing-carbon-simple-api-for-datetime-php">Carbon</a>.</p>

<h2>MasterView and BlogView</h2>

<p>I have talked about a Slim MasterView before while setting up a <a href="http://nesbot.com/2012/6/26/multilingual-site-using-slim">Multilingual site using Slim</a>.  The class is based on the same code but this time I add a bit more functionality.  Some default template variables are injected for urls and getting the site mode, pretty standard.  Another feature added is the ability to render partials.  This allows you to include other views without rendering it via the master template again.  The partial method includes the default injected variables plus anything specified in the <code>$data = array()</code> parameter.  The master template uses this internallly to include the <code>childView</code> and other sections of the template that have been separated into their own file.</p>

<pre><code class="php">
public function partial($template, $data = array())
{
   $this->injectDefaultVariables($data);
   extract($data);
   require $this->getTemplatesDirectory().'/'.$template;
}
</code></pre>

<p>This project then uses a <code>BlogView</code> class that extends the <code>MasterView</code> we just talked about.  It adds some project specific helpers like rendering a post, formatting the date etc.</p>

<pre><code class="php">
public function renderPost(Post $post)
{
   $this->partial(sprintf('posts/%s-%s.php', $post->posted->format('Y-n-j'), $post->slug));
}
</code></pre>

<p>The other fancier helpers use a callable closure parameter to execute with a post as the context.</p>

<pre><code class="php">
public function withPost($slug, $callable)
{
   $callable($this->posts->findBySlug($slug));
}

public function linkPost($slug, $callable)
{
   $post = $this->posts->findBySlug($slug);
   $callable($this->urlFullFor($post), $post->title);
}
</code></pre>

<p>These methods are used from the blog post view files.</p>

<pre><code class="php">
&lt;?$this->withPost("carpenters-house-last-to-get-attention", function ($post) {?>
   <p>The post &lt;?=$post->title?> was the one I was talking about.</p>
&lt;?});?>

&lt;?$this->linkPost("carpenters-house-last-to-get-attention", function ($url, $title) {?>
   <p>The post at the url &lt;?=$url?> with &lt;?=$title?> was the one I was talking about.</p>
&lt;?});?>
</code></pre>

<h2>Deployment</h2>

<p>Deployment of the site is done with a simple shell script.  Its easy enough for me to ssh in once in awhile to push.  I could set this up with a git post commit hook or at the very least a simple plink script.  If it were updated more frequently I would take the extra step to further automate it.  The deploy script, which is included in the repo, first creates a new directory based on <code>date +%Y%m%d%H%M%S</code>.  It then clones the repo to this new directory and runs a composer <code>install</code> to install the packages from the current <code>.lock</code> file.  It does not run an <code>update</code> as I don't want to install any newer packages than what was last tested and saved in the <code>.lock</code> file.  It continues by running the site bundle script.  Once that is complete it checks for some existing directories to make sure the deploy completed correctly before flipping the switch.  Finally it moves the <code>current</code> symbolic link to the new directory which makes the new version live.</p>

<p>If you look at the app.php file you'll notice that the logger is different in local vs live.  The local version uses a <code>/logs</code> directory and the live version uses a <code>/../logs</code>.  This is so the logs aren't wiped out with every deploy on live and the versions all write to a shared log up one directory from the webroots.  You may want to maintain my local setup on live to separate the logs out, but you can always relate the timestamp in the log to the version that was live at the time based on the directory names.  Since this site isn't deployed too often the single log directory is prefered.</p>

<h2>What about using xyz to make it faster?</h2>

<p>The current deployment is more than sufficient for me right now.  If I needed to take a next step then I could dramatically decrease server crunching by using a simple front end page cache.  You could easily setup a <a href="http://wiki.nginx.org/HttpRedis">HttpRedis</a> or <a href="http://wiki.nginx.org/HttpMemcachedModule">Memcached</a> cache and have the server only produce the pages on first load since the site is static between posts.  You could also off load the whole site to a CDN as well as its fairly static.</p>

<h2>Is this the last time?</h2>

<p>For now I think it is... but the next time I want to take on a new language or framework you can be sure this blog will get yet another rewrite.</p>]]></description>
   </item>
      <item>
      <title>Adding a SADDX command to Redis using Lua</title>
      <link>http://nesbot.com/2013/5/13/adding-a-saddx-command-to-redis-using-lua</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Mon, 13 May 13 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2013/5/13/adding-a-saddx-command-to-redis-using-lua</guid>
      <description><![CDATA[
<p>A popular use case for Redis is as an in-memory cache.  Most see it as an advanced memcached on steroids.  The <b>advanced</b> part is right there in its description on <a href="http://redis.io/">redis.io</a> : <b>advanced key-value store</b> that can contain strings, hashes, lists, sets and sorted sets.  If you don't know about the data structure server called Redis, then read about it at <a href="http://redis.io/">redis.io</a>.</p>

<h2>Why add if exists?</h2>

<p>An add if exists pattern is useful when using Redis as a memory cache server.  Suppose you have a blog that has posts and those posts have tags.  One day you introduce a new Redis memory cache into production.  When a post is read you neatly get all of the tags associated with the blog post. You of course are caching those tags using a Redis set.  The cache is empty so you grab the tags from the database and perform <code>SADD</code>'s to populate the cache. Good Work! But consider what happens when the first action is adding a new tag to an existing post.  You write the new tag to the database and <code>SADD</code> it into the cache.  Now the cached set just has the single tag in it and is missing any previous tags.  Now when a post is viewed the cached set exists and your incomplete list of tags is shown. Zoiks !</p>

<h2>Solutions</h2>

<p>There are a few ways to solve this, but the easiest is to only <code>SADD</code> the new value if the set already exists.  To accompany this, on reads when the cache is empty you repopulate the full list from your permanent datastore and everything works as expected.</p>

<h2>Atomicity</h2>

<p>Knowing that we should be checking for the set first, lets look at a potential implementation.</p>

<pre><code>
key = "post:11:tags"  // Lets assume the post id is 11
tag = "code"

if (redis.exists(key)) {
   redis.sadd(key, tag)
}
</code></pre>

<p>Another option would be to use <code>SCARD</code> and check for a <code>> 0</code> result.  The real issue though is there is a race condition.  Any number of things can occur between the check for existence and the <code>SADD</code>.  Another client could delete the set, you could hit a memory limit and Redis expires the key or an admin trying to be funny executes a <code>FLUSHALL</code> at the wrong time.  Any of those (and others) would cause the issue illustrated above to occur.  This is because the <code>EXISTS</code> and <code>SADD</code> when executed by a client do not run in an atomic way, other commands can get executed in between.  Redis does have the concept of transactions, but the result of one command in the transaction can not be used to influence another command in the same transaction.</p>

<p>The closest commands Redis has at the moment are <code>LPUSHX</code> and <code>RPUSHX</code>, but both only operate on lists so they don't currently help us.  There is also a <code>WATCH</code> command but if you are using Redis 2.6+ a simple Lua solution is much easier to understand.</p>

<h2>Enter SADDX and Lua</h2>

<p>According to the Redis documentation each Lua script command is executed atomically.  That is to say no other script or Redis command will be executed while a script is being executed.  This will protect us against our race condition. Yeah!</p>

<p>I started with the following Lua script.</p>

<pre><code>
if redis.call('type', KEYS[1]) == 'set' then
   return redis.call('sadd', KEYS[1], ARGV[1])
else
   return nil
end
</code></pre>

<p>I changed the check to use the <code>TYPE</code> command to check for the existence and type of the key. This script would support the following usage:</p>

<pre><code>
    EVALSHA 1c3bc2f2cae54a34f52206df01a549a07f240115 1 post:11:tags code
</code></pre>

<p>This however didn't work as expected and since this is also my first attempt with any Lua scripting the answer wasn't obvious for me at first.  After a bit I found the <code>type</code> function so I could determine what the <code>redis.call</code> was returing since it apparently wasn't a string.  Turns out it was of type <code>table</code>, which in Lua is an aggregate data type used for storing any type of collection (lists, sets, arrays, hashes etc.).  If you look at the <a href="http://redis.io/commands/type">TYPE</a> command its return value is indicated as a <code>status reply</code>.  The <a href="http://redis.io/commands/eval">EVAL</a> command documentation has a section on converting from Redis response types to Lua types and it indicates a status reply gets converted to a Lua table with a single <code>ok</code> field containing the status. Ah ha!</p>

<p>Now we can alter our Lua script to get to a working implementation.</p>

<pre><code>
if redis.call('type', KEYS[1]).ok == 'set' then
   return redis.call('sadd', KEYS[1], ARGV[1])
else
   return nil
end
</code></pre>

<p>We have successfully created an atomic <code>SADDX</code> command using Lua and can safely add if exists our tags.</p>

<p>For completeness sake, the <code>SCARD</code> command returns an integer so its implementation would look like:</p>

<pre><code>
if redis.call('scard', KEYS[1]) > 0 then
   return redis.call('sadd', KEYS[1], ARGV[1])
else
   return nil
end
</code></pre>

<h2>Closing notes</h2>

<p>As both have a <code>O(1)</code> time complexity (they'll each run at a consistent speed no matter how many keys or set members) you would just have to benchmark each using a simple scenario to determine which is faster.</p>

<p>This is generally a fire and forget type statement, so for either you could safely remove the else portion.  It seems the script returns a <code>nil</code> anyway, but I would favour leaving the return of the SADD command.  This allows you to check the return if required where a <code>nil</code> (or <code>null</code>, depending on your client language of choice) is returned when the set doesn't exist, a 0 if the value already exists in the set and a 1 if the value was added.</p>

<p>This leaves our final implementation as:</p>

<pre><code>
if redis.call('scard', KEYS[1]) > 0 then
   return redis.call('sadd', KEYS[1], ARGV[1])
end
</code></pre>]]></description>
   </item>
      <item>
      <title>My Parents Love: a speech to my Parents on their 50th wedding anniversary</title>
      <link>http://nesbot.com/2013/7/19/my-parents-golden-anniversary</link>
      <author>brian@nesbot.com (Brian Nesbitt)</author>
      <pubDate>Fri, 19 Jul 13 12:00:00 -0400</pubDate>
      <guid>http://nesbot.com/2013/7/19/my-parents-golden-anniversary</guid>
      <description><![CDATA[
<p><i>On July 6 my parents celebrated their 50th wedding anniversary and this is the speech I gave.</i></p>

<p>As I started writing this speech I thought I would do a little research to learn more about marriage.</p>

<p>Who could I ask? I went to my old reliable... the internet... since everything on there is of course true.</p>

<p>I started at Wikipedia, but that was too boring.</p>

<p>Next I went to twitter to see what I could learn there.  Sure enough some kind people had contributed their thoughts!</p>

<ul class="list">
<li>"The longest recorded marriage in history lasted 91 years and 12 days."</li>
<li>"Too Young for Marriage, Too Old for Games, Too Smart for Players"</li>
<li>"Marriage is like putting your hand into a bag containing 99 snakes and one eel. You may get the eel, but the odds are against you."</li>
<li>"There are only 3 times when it is appropriate for one's name to appear in a newspaper: birth, marriage, death. All else is scandal."</li>
<li>"Marriage is the process of finding out what kind of man your wife would have preferred..."</li>
</ul>

<p>... and finally I thought this one was particularly appropriate for tonight:</p>

<ul class="list">
<li>"No matter how long you're married, there will always be an opportunity to learn more about your spouse. Don't settle for what you already know. Keep learning."</li>
</ul>

<p>I found lots of other things as well, but most of it I can't repeat here tonight.</p>

<p>Next I thought, "Rather than reading from random individuals maybe I'll see what some famous people had to say."</p>

<ul class="list">
<li>I love being married. It's so great to find that one special person you want to annoy for the rest of your life.  Rita Rudner 
<li>I'd marry again if I found a man who had fifteen million dollars, would sign over half to me, and guarantee that he'd be dead within a year.  Bette Davis
<li>There's only one way to have a happy marriage and as soon as I learn what it is I'll get married again.  Clint Eastwood
<li>The heart of marriage is memories; and if the two of you happen to have the same ones and can savor your reruns, then your marriage is a gift from the gods.  Bill Cosby 
<li>Marriage destroyed my relationship with two wonderful men.  Marilyn Monroe 
<li>Marriage is like a game of chess except the board is flowing water, the pieces are made of smoke and no move you make will have any effect on the outcome.  Jerry Seinfeld 
</ul>

<p>Finally I decided to go to the experts to see what they think.  I asked my parents a few questions.  Lets call this the not so newlywed game.</p>

<p>Question #1 : Where was your first date? They both said "A walk over Champlain bridge"... and my dad was very specific adding they only got half way, stopped for a drink and walked back.</p>

<p>Question #2 : What was your first job?  They both answered correctly.  My mom's first job was a government stenographer (I had to look up on the internet what a stenographer was)! Dad's was peeling potatoes at the Dow's Lake boat house.</p>

<p>Question #3: What was your favourite trip together?  It was unanimous, Hawaii.  (I did notice that trip was not a family trip nor was I even on it!).</p>

<p>Question #4: Which of your bad habits around the house most annoy your spouse? They both knew what really pushed the other's buttons.  My mom apparently leaves her dishes on the table... My dad leaves his jeans on the bedroom floor.  Both pretty tame bad habits!</p>

<p>Question #5: How many girlfriends or boyfriends did you have before meeting each other? I found it funny that they both thought the other had only had 1 but that they had had 2.  My dad added that when they met my Mom was only 15 so I don't think she had that many!</p>

<p>In the end I decided we have some great leaders to follow as Amy and I approach our 10 year anniversary this October.  Amy's parents celebrated their 42nd anniversary a few days ago and of course mine are celebrating their 50th tonight.</p>

<p>Congratulations Mom and Dad ... Join with me in toasting my parents, wishing them many more anniversaries still to come.</p>

<p><small><i>Thanks to my wife for her help in writing this.  She will always have a better way with words than me.</i></small></p>
]]></description>
   </item>
   </channel>
</rss>
