

<rss version="2.0">
  <channel>
    <title>Dblock.org | Code</title>
    <description>technology website</description>
    <link>http://code.dblock.org/</link>
    <language>en-us</language>
    <image>
      <url>http://code.dblock.org/images/blog/blog.gif</url>
      <title>Dblock.org | Code</title>
      <link>http://code.dblock.org/</link>
      <width>72</width>
      <height>49</height>
    </image>
    
      <item>
       <title>Pressing the Big Scary Red Reset Button</title>
       <pubDate>Tue, 15 May 2012 14:02:23 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Last night I gave a talk on pressing the big scary red reset button at the <a href="http://www.ctoschool.org/">NY CTO School</a>. The first talk before me was by <a href="https://twitter.com/#!/malcolmcasey">@malcolmcasey</a>, CTO of <a href="http://www.skillshare.com/">Skillshare</a>, another awesome NYC startup. It’s a great meet-up for early team leads that want to learn from other technologists that have been doing this for a while.</p>  <p><a href="http://www.slideshare.net/dblockdotorg/pressing-the-big-scary-red-button"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=453&ShowThumbnail=false" width="260" height="202" /></a><a href="http://www.slideshare.net/dblockdotorg/pressing-the-big-scary-red-button"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=454&ShowThumbnail=false" width="260" height="201" /></a></p>  <p>I’ve reset a few projects in my life. None as big as Microsoft Windows Longhorn (Vista), which was a fun example of failure of monumental proportion. In 2006 Jim Alchin wrote in the Wall Street Journal: “Longhorn was crashing into the ground.” While he was credited with ultimately shipping Vista following a successful reset, it was one of Microsoft’s worse operating systems. Developers just no longer cared. You can see how a reset is by no means a guarantee of success. In fact, anecdotal evidence shows that 7 out of 10 projects that are reset still fail. And when projects fail there’s plenty of wrongs to be pointed out. Marketers will blame the product, product managers the technology and everybody will blame other people. A few will cite failure all around or an unstoppable death spiral.</p>  <p>I interviewed several CTOs when I was preparing this talk. It was really fun to hear about their experiences. They would usually start with a gasp and use a particular project reset vocabulary. “We slammed the brakes.” “Changed the wings on an airplane.” This might actually be a silly analogy – have you ever seen anyone attempt such a feat? No wonder most projects fail after a reset – taking the wings off in-flight means crashing into the ground, guaranteed. But if your reset is going too smoothly, feel free to add some drama as in <a href="http://www.youtube.com/watch?feature=player_embedded&v=316AzLYfAzw">this amazing video</a>.</p>  <p>I think that pressing the reset button on a clearly failing project is <em>always</em> the right thing to do. Put some numbers in perspective by measuring what value the project is yielding vs. what it costs. You may have sunken a ton of money into it, but you’re just bleeding more. To execute, get rid of all the chickens (people who aren’t committed to the project with their flesh and bones), trim some fat and time-box the reset. Use all the brownie points that you have earned until now with the rest of the company (that’s why it’s so important to invest in relationships inside an organization when things are going well, both up and down). Successful resets are very rewarding and have a long tail, but people tend to block out negative emotions associated with violence and doom that occurred in the past, so few will actually remember. You’re not a hero, you’re just doing your job.</p>  <p>Finally, things don’t need to reach the dire straits. Personally, I try to foster a culture where we experiment with everything. Want to build the new system with a different data store? Try it. Want to rewrite our entire UI with anotherframework.js? Go for it. You don’t need buy-in from me – you just need to be transparent and let everybody know what you’re doing. You’ll get plenty constructive criticism from others - make your own decisions. The job of a tech lead is to keep the output of the entire team massively positive, not to micromanage individual’s minutes. For every one developer stepping out of doing visibly productive feature work for a sprint another will step out to find a multiplying factor of 10 for something you’re building next. It’s a small price to pay for being awesome, as a team.</p>  <p>Slides: <a href="http://www.slideshare.net/dblockdotorg/pressing-the-big-scary-red-button">http://www.slideshare.net/dblockdotorg/pressing-the-big-scary-red-button</a></p></stripped></div><div><a href="http://code.dblock.org/pressing-the-big-scary-red-reset-button">Read</a></div></html>
         ]]>
       </description>
       <category>teams</category><category>learning</category><category>people</category><category>agile</category>
       <link>http://code.dblock.org/pressing-the-big-scary-red-reset-button</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/335</guid>
      </item>
     
      <item>
       <title>How Not to Rewrite Everything</title>
       <pubDate>Thu, 03 May 2012 13:47:24 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I wrote a blog post yesterday about <a href="http://artsy.github.com/blog/2012/05/01/how-to-start-small-with-big-data-and-google-analytics/">How to Start Small With Big Data and Google Analytics</a>. Essentially, it’s a jumpstart for fetching Google Analytics pageviews and merging the daily data with some domain knowledge. But it also asks an important question:</p>  <p><em>Why do so many companies write a homegrown pageviews tracking system? Between Google Analytics, Kissmetrics and many others, isn’t that a completely solved problem?</em></p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=451&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=452&ShowThumbnail=false" width="260" height="180" /></a></p>  <p><em><font size="1">this is a solved problem, too</font></em></p>  <p>I look back at my early years in software development and find myself rewriting a lot of software that has already been written by other people. It’s a typical overconfident engineer problem, where my initial reaction to anything created by other people is that it’s insufficient in too many ways. It started with early C++ code, where achieving performance and portability between many *nix systems and Windows was a nightmare – STL wasn’t nearly as good as today. I ended up rewriting everything, including String or Vector classes (an entire C++ library open-sourced as <a href="https://github.com/dblock/baseclasses">https://github.com/dblock/baseclasses</a>). I then went on to work for Microsoft where we were trying to build a 24/7 service that would not die from memory allocation failures. .NET didn’t exist then, MFC was out of the question because of it’s legendary reliability and so was the Microsoft version of the STL that was just merging with MFC. Open-source was not even part of Microsoft lingo. We built CoreSDK, a C++ library where I ended up rewriting everything, including String or Vector classes, again. I think I implemented at least a dozen versions of String in my life that went into some production code. Those were the days!</p>  <p>This decade’s software is way too complicated to rewrite everything. When I choose a platform or framework for a project, I like open-source ecosystems that encourage reuse. Adding third-party components in the .NET world is not commonplace. Adding dependencies in Java with Maven is better, until you need to make changes to the code in your dependencies. The Ruby world with Rubygems and Bundler gets it right: there’s virtually no overhead for using a third-party library. Node.js is a bit younger, but also gets it right.</p>  <p>Now that I can easily reuse third-party systems, I must try to remember that I should write less lines of code, introduce less operational overhead and create more positive product impact in a reasonable amount of time. It doesn’t mean I just want to slap together someone else’s components - things worth focusing on should be elements that serve my company’s core competencies or be educational for me, useful to the open-source community at large or just plain fun. While this sounds obvious, sticking to the guidelines and keeping myself accountable is a daily effort.</p>  <p>How do <em>you</em> avoid rewriting everything?</p></stripped></div><div><a href="http://code.dblock.org/how-not-to-rewrite-everything">Read</a></div></html>
         ]]>
       </description>
       <category>technology</category><category>art.sy</category><category>ruby</category><category>people</category>
       <link>http://code.dblock.org/how-not-to-rewrite-everything</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/334</guid>
      </item>
     
      <item>
       <title>How to Cross the Chasms of Your Technology Career</title>
       <pubDate>Sun, 22 Apr 2012 23:00:48 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I want to talk about your scope of influence as a Software Engineer and how to expand it.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=449&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=450&ShowThumbnail=false" width="494" height="331" /></a></p>  <p>Your scope of influence in your first piece of software is a function. You are parachuted in a well isolated world and are told to implement a simple algorithm. As you find your marks, you develop a component. Eventually they let you take on a small project. The entire company now knows about you. You switch jobs and become a familiar face in the city. You talk at a big conference and people from all over the world follow you on Twitter. You might, one day, invent something major and make an impact on humanity. Your life as a Software Engineer has just flashed in front of you.</p>  <p>I am somewhere in a shade of green in the graphic above. Crossing the lines between these circles is a difficult affair. If that is part of your goals, I want to suggest a few practical ways of expanding your scope of influence. Circles, that I feel I have crossed.</p>  <p><strong>From Component to Project</strong></p>  <p>Your component can be thrown away and replaced by another in no time. So can you. In order to cross this chasm, your commits must have global project impact. </p>  <p>Start with trivial tasks of standardizing the number of white spaces or tabs or by removing trailing spaces after meaningful code. Touch as many files as you can. I used to make commits of thousands of files because I was irritated by the lack of periods in code comments. Am I crazy? The truth is that I was terrified about modifying so many files at once and that prevented me from refactoring large chunks of architecture that was very broken. So changing whitespaces or adding periods was a useless exercise that helped me. When you’re comfortable with modifying code left and right, find a major piece of infrastructure to rip out and replace by something better. I remember swapping a C++ core library from underneath a huge system, a seminal moment.</p>  <p><strong>From Project to Company</strong></p>  <p>Nobody knows who you are until you’ve built something that many people want. In order to cross this chasm, seek a need that goes beyond your team. </p>  <p>Around 2001 I needed a tool to send a massive amount of e-mail to stress test some service. I couldn’t find a decent one, so I wrote something new. I put it on an intranet site and kept updating it. Eventually a lot of people with similar needs in the company used it. Then I  started another larger tool to help my team with our complicated builds. I made an intranet site for that too, and it took off. Six months later I was doing that project full time  with executive support and a team of five developers.</p>  <p>When building something that your entire company needs you learn much more than code. You have actual customers and you suddenly find yourself needing to talk to people, presenting the project to them and arguing with skeptics. Working with people is hard and providing a useful service within a corporation is a good place to start.</p>  <p><strong>From Company to City</strong></p>  <p>You’ll find yourself solving the same type of problems as your friends working at other companies. In order to cross this chasm, organize a visit to a friendly business. Go with a million questions and drag your fellow coworkers. Bring pastries.</p>  <p>Every time I lift my head from the computer and visit another tech startup in NYC I come out pumped. I learn so much and meet new Engineers! The first company I visited with my current team was Foursquare about a year and a half ago and the last as of last week was Rent-The-Runway. I met dozens of new techies in between. Every single time, by brainstorming ideas I changed my mind on how to build something or at least it made me think. </p>  <p>When you have built a solid network that includes technologists from other companies, you have crossed this chasm. It will help you hire coworkers and find a new job. You’re no longer behind artificial corporate barriers, you’re free.</p>  <p><strong>From City to World</strong></p>  <p>What did you do when you crossed the chasm from project to company? You sought a company-wide need and made a solution public within the walls of your business. Time to do it again, but in public. Scared of so many eyes? The truth is that nobody cares until you build something really good. So my philosophy is that anything that is not core intellectual property can be open-sourced and is always a great learning experience. When you build something good, you’ll remember the moment when a developer from another continent makes a pull request into your project on Github!</p>  <p>You must also write. Start a technical blog. And don’t forget to give a 3 minute lightning talk about your open-source project at a meet-up. Standing and talking in front of people is hard, but they need to put a face to your name. Slowly graduate to big conferences. On to conquer the world!</p>  <p><strong>World to Humanity</strong></p>  <p>Don’t ask me. Most people that had an impact on humanity have written books, given TED talks and won Nobel prizes. Honestly, I have no idea and am certainly very far from any of these. Help?</p></stripped></div><div><a href="http://code.dblock.org/how-to-cross-the-chasms-of-your-technology-career">Read</a></div></html>
         ]]>
       </description>
       <category>teams</category><category>teaching</category><category>learning</category><category>hiring</category><category>technology</category><category>jobs</category><category>organizations</category><category>people</category><category>me me</category>
       <link>http://code.dblock.org/how-to-cross-the-chasms-of-your-technology-career</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/333</guid>
      </item>
     
      <item>
       <title>You Have to Stop Saying Your Experience is Under NDA in Interviews</title>
       <pubDate>Mon, 16 Apr 2012 14:19:10 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I talked to a developer recently. He said:</p>  <blockquote>   <p><em>“I cannot talk about this project, because it’s under NDA.” … followed by silence</em></p> </blockquote>  <p>First, you’re confusing “NDA” and “Classified” or “Top Secret”. I worked on Classified projects. Or have I? You’ll never know. But I have a t-shirt that says: “my project is so secret, I don’t even know what I am doing”. And that’s precisely how you sound.</p>  <p><img alt="Conspiracy Keanu - my project is so secret I DON'T EVEN KNOW WHAT I'M DOING" src="http://cdn.memegenerator.net/instances/400x/18689460.jpg" width="173" height="173" /></p>  <p>Can you please tell me something useful?</p>  <p>Start by describing your project in abstract terms without violating any of these commitments. For example, my uncle worked in a classified nuclear facility near Petyagorsk in former Soviet Union. At least I think he has. He was smuggled to Israel where all that classified stuff was quickly declassified and translated to Hebrew. I am guessing that he worked on some weapons systems that could destroy half of the planet or a small satellite. I know he could talk about his work in very abstract terms. And more specifically, he could definitely explain general issues with building explosives from small to nuclear, without revealing anything classified. So can you.</p>  <blockquote>   <p><em>“Our project was in the daily deals space. I cannot describe the exact purpose of the project, but it involved deals … daily ones. One of the interesting problems I worked consisted of moving a million instances of data between 3 and 5Kb each from a node located in South America to a node in the U.S. I used MongoDB to store the data and a Redis queue for processing.”</em></p> </blockquote>  <p>Now we’re talking.</p></stripped></div><div><a href="http://code.dblock.org/you-have-to-stop-saying-your-experience-is-under-nda-in-interviews">Read</a></div></html>
         ]]>
       </description>
       <category>hiring</category><category>people</category>
       <link>http://code.dblock.org/you-have-to-stop-saying-your-experience-is-under-nda-in-interviews</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/332</guid>
      </item>
     
      <item>
       <title>Grape 0.2.0 Released</title>
       <pubDate>Thu, 29 Mar 2012 14:55:40 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>After almost a year of active development with 200+ commits, Grape 0.2.0 has finally been released. It’s the code from the “frontier” branch that we’ve been using in production for quite a while.</p>  <p>Grape is an API DSL. If you’re building a RESTful API today, this is a great place to start. Grape lives at <a href="https://github.com/intridea/grape">https://github.com/intridea/grape</a>.</p>  <p>Here’re the 0.2.0 highlights:</p>  <ul>   <li>Vendor-based versioning</li>    <li>Model exposures presentation layer</li>    <li>PATCH and OPTIONS HTTP methods</li>    <li>API description blocks, reflection and introspection</li>    <li>Modules</li>    <li>Cookies</li>    <li>Anchoring</li> </ul>  <p>Grape is a great project. It’s always an honor to contribute to systems written by much stronger Ruby developers. Many of my pull requests would get rejected and <a href="https://github.com/mbleigh">Michael</a> would then rewrite the feature with a much improved architecture (API modules is one of those). I feel like I really learned something in this process. Open-source FTW!</p></stripped></div><div><a href="http://code.dblock.org/grape-020-released">Read</a></div></html>
         ]]>
       </description>
       <category>grape</category><category>ruby</category>
       <link>http://code.dblock.org/grape-020-released</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/331</guid>
      </item>
     
      <item>
       <title>Paging and Iterating Over Large Mongo Collections</title>
       <pubDate>Wed, 28 Mar 2012 13:23:09 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Sometimes you need to iterate over a large MongoDB collection. The biggest issue is that, by default, cursors timeout after 10 minutes of inactivity. For very large collections it’s not uncommon to take longer than that to process results and you get an exception half way through the iteration. A cursor is a server-side construct, how about a client-side cursor?</p>  <p>Here’s a Mongo Ruby iterator that will call Mongo::Collection.find in increments.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>module Mongo</li> <li class="even">  class Collection</li> <li>    def find_all(query = {}, by = 1000, &block)</li> <li class="even">      idx = 0</li> <li>      while ((results = find(query, { :limit =&gt; by, :skip =&gt; idx })) && results.count(true) &gt; 0)</li> <li class="even">        results.each do |result|</li> <li>          yield result</li> <li class="even">          idx += 1</li> <li>        end</li> <li class="even">      end</li> <li>      self</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>And a Mongoid iterator built into Mongoid::Criteria.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>module Mongoid</li> <li class="even">  class Criteria</li> <li>    def each_by(by = 1000, &block)</li> <li class="even">      idx = 0</li> <li>      set_limit = options[:limit]</li> <li class="even">      while ((results = clone.limit(by).skip(idx)) && results.any?)</li> <li>        results.each do |result|</li> <li class="even">          return self if set_limit and set_limit &gt;= total</li> <li>          yield result</li> <li class="even">          idx += 1</li> <li>        end</li> <li class="even">      end</li> <li>      self</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>Of course you must be careful that the collection doesn’t change during the iteration. If you add or remove an item before you, or will skip elements or process some elements twice.</p></stripped></div><div><a href="http://code.dblock.org/paging-and-iterating-over-large-mongo-collections">Read</a> | Updated 3/28/2012</div></html>
         ]]>
       </description>
       <category>mongoid</category><category>mongodb</category><category>ruby</category>
       <link>http://code.dblock.org/paging-and-iterating-over-large-mongo-collections</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/330</guid>
      </item>
     
      <item>
       <title>How To Convert Numbers Into Words in Ruby (with numbers_and_words)</title>
       <pubDate>Fri, 23 Mar 2012 21:37:49 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>You’d think someone has implemented simple conversion of numbers into English by now? For example 42 becomes “forty-two”.</p>  <p>I found a few interesting posts, a couple of gems and even a competition. All had issues that fit in two buckets: they could only do English or their implementation was scary. While I didn’t really *need* a converter that worked for different languages, none of the libraries inspired much confidence. Finally, I ran into a I18n implementation that was generic, well implemented and properly tested for Russian. It needed some minor English work, but you can be sure that the Russian version is *much* more complicated.</p>  <p>A few pull requests later, please welcome a new gem, <a href="https://github.com/kslazarev/numbers_and_words">numbers_and_words</a>. <a href="https://github.com/kslazarev/">Kirill</a> designed the library with conversion strategies and proper localization in-mind.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>I18n.with_locale(:en) { 42.to_words }</li> <li class="even">I18n.with_locale(:ru) { 42.to_words }</li> </ol> </div> </div> </div>  <p>These produce "forty-two" and "сорок два". </p>  <p>And a fun one.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>2935174315119654654654654654.to_words</li> </ol> </div> </div> </div>  <p>This is obviously “two octillion nine hundred thirty-five septillion one hundred seventy-four sextillion three hundred fifteen quintillion one hundred nineteen quadrillion six hundred fifty-four trillion six hundred fifty-four billion six hundred fifty-four million six hundred fifty-four thousand six hundred fifty-four”.</p>  <p>Can someone please contribute a Spanish version next?</p>  <p><a href="https://github.com/kslazarev/numbers_and_words">https://github.com/kslazarev/numbers_and_words</a></p></stripped></div><div><a href="http://code.dblock.org/how-to-convert-numbers-into-words-in-ruby-with-numbersandwords">Read</a> | Updated 3/24/2012</div></html>
         ]]>
       </description>
       <category>ruby</category>
       <link>http://code.dblock.org/how-to-convert-numbers-into-words-in-ruby-with-numbersandwords</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/329</guid>
      </item>
     
      <item>
       <title>VMWareTasks Moved to Github</title>
       <pubDate>Tue, 20 Mar 2012 13:14:16 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I moved the popular VMWareTasks C# library from CodePlex to Github. </p>  <p>The new home is: <a href="https://github.com/dblock/vmwaretasks">https://github.com/dblock/vmwaretasks</a>. There’s also a <a href="http://groups.google.com/group/vmwaretasks">new Google Group</a> for discussions.</p>  <p><a href="https://github.com/dblock/vmwaretasks"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=448&ShowThumbnail=false" width="160" height="63" /></a></p>  <p>I haven’t been using VMWare ESXi since their new licensing scheme started milking customers, even for API access, but it remains a great product and as far as I know most people who write C# code to talk to ESXi are using VMWareTasks. Several people have been sending patches recently, Github will make this process a lot easier.</p></stripped></div><div><a href="http://code.dblock.org/vmwaretasks-moved-to-github">Read</a></div></html>
         ]]>
       </description>
       <category>github</category><category>vmware</category>
       <link>http://code.dblock.org/vmwaretasks-moved-to-github</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/328</guid>
      </item>
     
      <item>
       <title>Avoiding Production Disasters and The Value of Patience in Software Development</title>
       <pubDate>Mon, 19 Mar 2012 12:28:43 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I am not a patient person. But years of software practice have taught me how to take my time while coding or how to, otherwise, remove time from the equation.</p>  <p><strong>Manual Tasks Become Features</strong></p>  <p>Otherwise known as <em>process becomes automation</em>.</p>  <p>You need a lot of patience when operating a manual change on a live system. You’re always <em>this</em> close to dropping the <em>users</em> table. So I learned a decent way to prevent mistakes: always run commands in a test environment, first. But that’s the same as walking on a cable between two chairs, before trying it between two skyscrapers – there’s still no safety net.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=438&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=439&ShowThumbnail=false" width="277" height="331" /></a></p>  <p><em><font size="1">“first, he tried it at home between two chairs”</font></em></p>  <p>Instead, transform any manual task into a feature. In the Ruby world we write Rake tasks. </p>  <p>The cost of transforming a task into a feature is about half a day of work. But it’s still less than one production disaster for every 100 such instances.</p>  <p><strong>Automated Tasks Become Business Logic with Tests</strong></p>  <p>Automation is good, but testing is better. Consider the following task that sends some kind of reminder e-mail.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>desc "Send a reminder to all users that haven't been reminded yet."</li> <li class="even">  task :remind =&gt; :environment do |t, args|</li> <li>    User.all.each do |user|</li> <li class="even">      next if user.reminded?</li> <li>      user.update_attributes!({ reminded_at: Time.now.utc })</li> <li class="even">      ReminderMailer.delay.reminder_email(user)</li> <li>    end</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>    <p>It’s pretty concise. Unfortunately, <em>user.reminded?</em> has a bug and you now have a communication disaster on your hands. </p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=440&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=441&ShowThumbnail=false" width="277" height="331" /></a></p>  <p><font size="1">"he just reminded a million users that their delinquent account is about to be suspended”</font></p>  <p>We can move this entire logic into the <em>User</em> model and write a test.</p>      <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>class User</li> <li class="even">    def reminded?</li> <li>        !! reminded_at</li> <li class="even">    end</li> <li> </li> <li class="even">    def remind!</li> <li>        raise "reminder already sent" if reminded?</li> <li class="even">        update_attributes!({ reminded_at: Time.now.utc })</li> <li>        ReminderMailer.delay.reminder_email(self)</li> <li class="even">    end</li> <li>end</li> </ol> </div> </div> </div>   <p>The test can cover other important aspects, such as the actual source and destination of the e-mail.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>describe "remind!" do</li> <li class="even">    before :each do</li> <li>      @user = Fabricate :user</li> <li class="even">    end</li> <li>    it "should send a reminder to a user" do</li> <li class="even">      emails_count = ActionMailer::Base.deliveries.count</li> <li>      @user.remind!</li> <li class="even">      ActionMailer::Base.deliveries.count.should == emails_count + 1</li> <li>      reminder_email = ActionMailer::Base.deliveries.last</li> <li class="even">      reminder_email.from.first.should == "support@acme.com"</li> <li>      reminder_email.to.first.should == @user.email</li> <li class="even">      @user.reminded?.should be_true</li> <li>    end</li> <li class="even">    it "should not send a reminder email more than once" do</li> <li>      @user.remind!</li> <li class="even">      emails_count = ActionMailer::Base.deliveries.count</li> <li>      lambda { @invitation.remind! }.should raise_error("reminder already sent")</li> <li class="even">      ActionMailer::Base.deliveries.count.should == emails_count</li> <li>    end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>And the task is simpler.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>desc "Send a reminder to all users that haven't been reminded yet."</li> <li class="even">  task :remind =&gt; :environment do |t, args|</li> <li>    User.all.each do |user|</li> <li class="even">      next if user.reminded?</li> <li>      user.remind!</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>The cost of this change depends on the complexity of the task, but it tends toward zero. Tests take time to implement, but save debugging and regression time. Operational, or “machine” cost is roughly half a day, because the changes must go through continuous integration and a deploy before they can be run.</p>  <p><strong>Friday Changes Become Monday Changes</strong></p>  <p>Why do something today when you can do it tomorrow?</p>  <p>It’s Friday night and happy hour is about to start. Plan that next deploy for Monday morning, when everybody is in the office.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=442&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=443&ShowThumbnail=false" width="277" height="331" /></a></p>  <p><font size="1">“she just spent her week-end undoing Friday’s mess”</font></p>  <p>Spending a week-end in the office fixing what you (or someone else) broke on a Friday shoots your Monday’s productivity. You’ll feel like exhausted heroes, at the cost of three days of work (week-end included) multiplied by the number of people involved.</p>  <p><strong>This Week Becomes This or Next Sprint</strong></p>  <p>I firmly believe in under-promising and over-delivering. </p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=444&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=445&ShowThumbnail=false" width="277" height="331" /></a></p>  <p><em><font size="1">“he over-promised and under-delivered”</font></em></p>  <p>Never promise anything for tomorrow, day-after-tomorrow or even this week. </p>  <p>I see the best engineers learn to answer requests with “this sprint” and working really hard and getting it done for the next day. I love that. They don’t have an impossible deadline, and aren’t required to cut corners and can do things patiently (implement the request as a feature, write tests and get a code review).</p>  <p>The person on the receiving end is juggling a hundred things too, and generally they don’t expect anything to be done immediately, either. They also never remember when something was done in a day vs. two or five, but they remember well when something made in a hurry produced a production outage.</p>  <p><strong>Asking a Person Becomes Asking The Team</strong></p>  <p>As the team via the team lead when you need a feature.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=446&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=447&ShowThumbnail=false" width="278" height="331" /></a></p>  <p><em><font size="1">“she will gladly implement your feature request, right now”</font></em></p>  <p>We’re creatures of habit. So we ask the same person who implemented our previous request to do it again. Asking a team lead is really not a matter of process, – I don’t get offended when someone goes directly to a developer to ask for something (in fact, I love when this happens in some cases) – it’s a matter of actually getting you what’s important, first. A team lead has a complete view of everything that’s going on and will be able to find hands for your request. It will get done much sooner.</p>  <p>***</p>  <p>It’s Friday afternoon and you’re about to make a clean break and grab a beer. Someone wants you, a developer, to e-mail a million users and remind them about their account being suspended. Rewind through my blog post.</p></stripped></div><div><a href="http://code.dblock.org/avoiding-production-disasters-and-the-value-of-patience-in-software-development">Read</a></div></html>
         ]]>
       </description>
       <category>teams</category><category>testing</category><category>people</category>
       <link>http://code.dblock.org/avoiding-production-disasters-and-the-value-of-patience-in-software-development</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/327</guid>
      </item>
     
      <item>
       <title>Full Client-Server Negotiate SSO in Java w/o a Web Server using WAFFLE</title>
       <pubDate>Thu, 15 Mar 2012 23:50:01 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Nice job from <a href="https://github.com/gschrader">@gschrader</a>.</p>  <blockquote>   <p><em>This is an example of using WAFFLE to authenticate a client to a server using single sign on (SSO) using the Negotiate Security Support Provider.  It passes messages back and forth using Netty.</em></p> </blockquote>  <p><a href="https://github.com/gschrader/ssoexample">https://github.com/gschrader/ssoexample</a></p></stripped></div><div><a href="http://code.dblock.org/full-client-server-negotiate-sso-in-java-wo-a-web-server-using-waffle">Read</a></div></html>
         ]]>
       </description>
       <category>waffle</category><category>security</category><category>java</category>
       <link>http://code.dblock.org/full-client-server-negotiate-sso-in-java-wo-a-web-server-using-waffle</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/326</guid>
      </item>
     
      <item>
       <title>How Long Does it Take to Create a 12 Lecture, 8 Week Course</title>
       <pubDate>Wed, 14 Mar 2012 15:08:01 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>My family counts many teachers. My grandparents were teachers, my father started as a school English teacher and is now a University professor. My wife changed her successful career to become a teacher.</p>  <p>My own first encounter with education as an instructor was teaching elder kids the proper pronunciation and the meaning of the Beatles songs in the depths of the winter coat check in Moscow school No. 80 (now 1266). I was probably 10. Those kids were 8th graders, probably 15. Why me? I could speak English and my dad had a few rare Beatles tapes. I was also a terrible singer, but I knew what they were singing. Without realizing it, I encountered a magical desire to learn from a group that bullied me into teaching them.</p>  <blockquote>   <p>Sgt. Pepper's Lonely Hearts Club Band …</p> </blockquote>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=434&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=435&ShowThumbnail=false" width="277" height="331" /></a><a href="http://code.dblock.org/ShowPicture.aspx?id=436&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=437&ShowThumbnail=false" width="277" height="331" /></a></p>  <p><em><font size="1">the school I went to and Gagarin Square nearby</font></em></p>  <p>I got an opportunity to teach a Ruby-on-Rails class to a group of 15 developers at <a href="http://generalassemb.ly">GeneralAssemb.ly</a> around September last year. I have given a few 2-4 hour talks at GA to various groups and I was excited by this prospect. The audience in my talks was always eager to learn and I met a large number of smart people through the exercise. <a href="http://www.linkedin.com/pub/matthew-owens/4/b96/3a8">Matt</a>, who works full time for GA, would produce a properly structured, six week affair, paid and supported, as with all GA educational events. So we settled on a good size for the class, took lots of student applications, found an experienced RoR teaching assistant, <a href="http://www.linkedin.com/in/dimroc">Dimitri</a>, secured a space, arranged office hours and a lot more. The big missing piece was a curriculum that I began working on.</p>  <p>Learning in a classroom is not the same as learning with a tutorial. An online document doesn’t look you in the eyes or help you when you’re stuck. It can’t monitor the room for blank stares of forgotten students. It doesn’t even sweat when live coding doesn’t translate into working software. And a tutorial can’t help you with issues unrelated to the immediate task, such as setting up a working local database or editor. But I learned with a tutorial and I always wondered whether I could be better at what I do had I learned wit ha mentor. I decided to build a new curriculum that would transmit my working RoR knowledge and deeper understanding of the system over the six weeks of tutorship, instead of six months of copying, pasting, stumbling and googling.</p>  <p>How long does it take to create a 12-lecture, 8-week course? </p>  <p>I spent between two and four hours per lecture researching and writing it, then about two hours preparing exercises and doing a dry-run through my own material. This is essential to avoid stumbling during live coding - just like for an important demo or talk, the last thing you want when presenting a course is to type some code and fail in front of an audience. I also created, assigned, reviewed and graded exercises after the first six lectures, which usually takes fifteen to thirty minutes per student, lets say another four hours. And I prepped a <a href="http://code.dblock.org/crafting-a-ruby-on-rails-course-for-developers">talk at NYC.rb</a> too :) This adds up to about 60 hours of preparing for the lectures, about 25 hours of total homework, 24 hours of actual lecturing, 8 hours of project collaborative coding in a classroom (we extended the class by two weeks for this). Grand total 117 hours, which is very roughly three weeks of full time work.</p>  <p>Thanks to GA, the curriculum is now open-source and free for non-commercial use. If you’re teaching a class, consider using it! You can find it at <a href="https://github.com/generalassembly/ga-ruby-on-rails-for-devs">https://github.com/generalassembly/ga-ruby-on-rails-for-devs</a>. And, while we had our <a href="https://github.com/generalassembly/ga-ruby-on-rails-for-devs/pull/21">first public pull request</a> this morning to fix a couple of broken links, I can’t wait for some feedback and substantial contributions.</p></stripped></div><div><a href="http://code.dblock.org/how-long-does-it-take-to-create-a-12-lecture-8-week-course">Read</a> | Updated 3/14/2012</div></html>
         ]]>
       </description>
       <category>teaching</category><category>learning</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/how-long-does-it-take-to-create-a-12-lecture-8-week-course</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/325</guid>
      </item>
     
      <item>
       <title>Crafting a Ruby on Rails Course for Developers</title>
       <pubDate>Wed, 14 Mar 2012 02:33:58 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><a href="http://www.slideshare.net/dblockdotorg/crafting-a-rubyonrails-course-for-developers"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=433&ShowThumbnail=false" width="260" height="203" /></a></p>  <p>Today I gave a talk to a packed NYC.rb about <a href="http://www.meetup.com/NYC-rb/events/46696902/">crafting a Ruby-on-Rails course for developers</a>. I’m working on a blog post about classroom education, but in the meantime, here’re a few links.</p>  <p>The Open-Source Curriculum @ <a href="https://github.com/generalassembly/ga-ruby-on-rails-for-devs">https://github.com/generalassembly/ga-ruby-on-rails-for-devs</a></p>  <p><a href="http://www.slideshare.net/dblockdotorg/crafting-a-rubyonrails-course-for-developers">Slides from the Presentation on SlideShare</a></p>  <p><strong>Demo Stashboards, Students’ Projects</strong></p>  <p><a href="https://github.com/jameslin101/stashboard">https</a><a href="https://github.com/jameslin101/stashboard">://</a><a href="https://github.com/jameslin101/stashboard">github.com/jameslin101/stashboard</a>: a clean Stashboard clone</p>  <p><a href="https://github.com/MedText/stashfu">https://</a><a href="https://github.com/MedText/stashfu">github.com/MedText/stashfu</a>: Stashboard as a service</p>  <p><a href="https://github.com/generalassembly/boardroom">https://</a><a href="https://github.com/generalassembly/boardroom">github.com/generalassembly/boardroom</a>: Stashboard with voice-over-ip-activated control</p>  <p>I want to thank the audience for attending en-masse, the students who demoed their Stashboard clones, GA and the course sponsors. Some of the students are looking for a Ruby-on-Rails programmer job, reach out to Matthew Owens at GeneralAssemb.ly (mowens[at]generalassemb.ly) if you’re interested and hiring.</p></stripped></div><div><a href="http://code.dblock.org/crafting-a-ruby-on-rails-course-for-developers">Read</a></div></html>
         ]]>
       </description>
       <category>teaching</category><category>learning</category><category>technology</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/crafting-a-ruby-on-rails-course-for-developers</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/324</guid>
      </item>
     
      <item>
       <title>How to Redirect Bang Hash Urls</title>
       <pubDate>Fri, 09 Mar 2012 13:37:58 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Sometimes you <strike>type a hash-bang URL too fast</strike> you send many e-mails with an important URL having the bang first. No big deal. Read about it how to redirect it <a href="http://artsy.github.com/blog/2012/03/06/how-to-redirect-bang-hash-urls/">on the Art.sy Engineering blog</a>.</p></stripped></div><div><a href="http://code.dblock.org/how-to-redirect-bang-hash-urls">Read</a></div></html>
         ]]>
       </description>
       <category>art.sy</category><category>rails</category>
       <link>http://code.dblock.org/how-to-redirect-bang-hash-urls</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/323</guid>
      </item>
     
      <item>
       <title>Why You Should Leave Microsoft, Too</title>
       <pubDate>Mon, 05 Mar 2012 12:50:23 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I read Bertrand’s <a href="http://weblogs.asp.net/bleroy/archive/2012/02/29/leaving-the-evil-empire.aspx">post on “Tales from the Evil Empire”</a> about him leaving Microsoft this morning. Congratulations. We have never met, but your blog was in my RSS feed for a very long time. I would regularly learn valuable .NET-related lessons - my blog happened to be hand-written in .NET and I was still writing quite a bit of it myself with a few open-source projects like <a href="http://dotnetinstaller.codeplex.com/">dotNetInstaller</a> or <a href="http://resourcelib.codeplex.com/">ResourceLib</a>.</p>  <p>I left Microsoft in October 2004 to move to New York. If you have worked at Microsoft for over 5 years, and your management, peers and reports value and consider you above average, you should leave too. In fact, if you have worked in any large company, including Google or Goldman Sachs for as long, it may be that time.</p>  <p><strong>Open Source Changed Everything</strong></p>  <p>Bertrand writes:</p>  <blockquote>   <p><em>Almost all sectors of human activity have started to move away from a hierarchical, top-down model, to a distributed one. It takes the form of open source, of peer-to-peer, or of social networks.</em></p> </blockquote>  <p>Agreed 100%. That’s pretty huge.</p>  <p>Team heads, including myself, are making open-source their foundation. This means building non-core intellectual property components as open source. That’s easily 2/3 of the code you write and we all want to focus on our core competencies. Hence open-source is a better way to develop software, it’s like working for a company of the size of Microsoft, without the centralized bureaucracy and true competition.</p>  <p>Break free and start getting paid for contributing to open-source.</p>  <p><strong>Big Companies Are Always Looking Inward</strong></p>  <p>The amount of accumulated tools and legacy force big corporations to look inward, a lot. Which, in turn, changes the meta-level of your skills. This is a syndrome of  a lot of Google engineers: the amount of infrastructure available to you at Google looks impressive. To their credit Google does open-source a lot of code, but between existing internal distributed file systems and execution grids you actually aren’t capable of building a working large scale service from scratch. It’s like living in a bubble.</p>  <p>In reality, you have everything to learn.</p>  <p><strong>Your Skills Don’t Match New Tech Jobs</strong></p>  <p>Enterprises keep what works to make money. How much overlap do your skills have with a typical startup of 2012? Lets make a list: RoR, Python, PHP, Javascript MVCs? Have you ever deployed an EC2 instance or even heard of Heroku? Have you made a single REST APIs or are you writing SOAP RPC? What kind of Java are you writing today? That’s actually a lot like me a year and a half ago – I am still bewildered anyone wanted to hire me!</p>  <p>If you don’t press the reset button new hires at your company in another five years will obsolete you.</p>  <p><strong>Your Resume Will Look Identical in a Year or Another Five</strong></p>  <p>How much do you read into a resume when you interview people? Your resume will read the same in two years. If you’re an individual contributor it will have a minor technology refresh and maybe a new product, but it will read the same. If you’re a team lead, you might get a few more direct reports. You’ll get that next promotion level – I left MSFT at 65 or 66, can’t remember. Nobody outside of MSFT cared about that.</p>  <p>Five vs. seven years makes no difference, but 2 years at a startup is everything.</p>  <p><strong>You Could Work with an A-Team</strong></p>  <p>Corporations don’t fire idiots as fast and aren’t able to always retain the best, especially entrepreneurial kind. You end up with a lot of average people that breed more average people. That, in turn, demotivates you. Even if you score a great sub-team, you are still ten levels below decision makers that will can it the first time they get a chance.</p>  <p>Finding a new team or starting your own is the most straightforward way to work with an A-Team. </p>  <p><strong>You Can Always Return</strong></p>  <p>Large corporations with good finances will always want to take you back. They are constantly starved for talent and even more starved for former and successful employees that know how to navigate the company. It’s a huge win for a manager to get someone who left by their own will, back. I get a concrete solicitation from Microsoft every three months. It’s flattering.</p>  <p>In my experience, few people return to their mother ship. But it’s there.</p>  <p><strong>Want to Jump?</strong></p>  <p>None of this may be for you. But, as always, my offer to help you stands. If you want to work for any of the companies in the <a href="http://nytm.org/made/">NYTM.org list</a> after reading this post, drop me a note. I’ll help you with direct introductions to the hiring managers.</p></stripped></div><div><a href="http://code.dblock.org/why-you-should-leave-microsoft-too">Read</a></div></html>
         ]]>
       </description>
       <category>startups</category><category>new york</category><category>hiring</category><category>technology</category><category>jobs</category><category>people</category>
       <link>http://code.dblock.org/why-you-should-leave-microsoft-too</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/322</guid>
      </item>
     
      <item>
       <title>Github Hacked: Things to Do on Monday</title>
       <pubDate>Mon, 05 Mar 2012 02:17:03 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>You should take a serious look at your application and write some tests, first thing Monday.</p>  <p>I would write integration tests with real data that attempt to exploit the issues that were exposed by the Github hack. Even if you’re sure of your code, sit down and write a few tests, just to be double-sure. Don’t do a code review, write some code that will tell you, 100%, whether you have problems or you don’t. </p>  <p>I see two major attack vectors.</p>  <p><strong>Mass Assignment</strong></p>  <p>Read <a href="http://homakov.blogspot.com/2012/03/how-to.html#">Homakov’s post</a>. If it’s not clear, read it again until it’s clear.</p>  <p>Given models Parent and Child where children belong to parents - can I post a parent’s ID to a form that updates a child and therefore change which parent a child belongs to? If so, you have a problem. Go fix it first thing in the morning in a systematic way, by writing a test that reproduces the issue, then by protecting the attributes with an <em>attr_accessible</em> method. This will filter out everything that’s not in the list when you call <em>update_attributes</em>. Make sure you just use this on all models, all the time.</p>  <p>A variation of this problem is <em>garbage in, garbage out</em>. This affects systems backed by NoSQL document databases. Make sure you aren’t writing random attributes that come from a form into your model. In a relational database you get an exception because the field doesn’t match the schema. In a document store you have just stored junk. It may be harmless or harmful, but you’d rather not find out the hard way.</p>  <p>We use a home grown hash map to whitelist attributes for historical reasons, but <em>attr_accessible</em> does the job just fine.</p>  <p><strong>Identity Confusion</strong></p>  <p>Whitelisting attributes only works when you actually don’t need to assign relationships. Do you pass an identity for a Widget as a parameter, maybe in a URL? Do widgets belong to different users? If so, write a test that ensures that a user that doesn’t have access to this Widget cannot modify it. </p>  <p>My recommendation is to use something like <a href="https://github.com/ryanb/cancan">CanCan</a> and to check authorization in a single layer. You spell out who can create/retrieve/update/delete models and enforce this with a single <em>has_authorization_to?.</em> We do this in our API layer systematically. We also learned to key off <em>current_user</em> as much as possible. So if you’re modifying widgets that belong to <em>current_user</em>, you won’t find a widget with a rogue ID by doing <em>current_user.widgets.find(someone_elses_widget_id)</em>.</p>  <p><strong>Dear Github</strong></p>  <p>I still love you. This happens to the best people out there. Shameless plug for my former <a href="http://www.teamshatter.com/">Team SHATTER</a>, if you want a list. Move on and learn from it. </p>  <p> </p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=431&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=432&ShowThumbnail=false" width="170" height="163" /></a></p></stripped></div><div><a href="http://code.dblock.org/github-hacked-things-to-do-on-monday">Read</a></div></html>
         ]]>
       </description>
       <category>github</category><category>rails</category><category>shatter</category><category>security</category>
       <link>http://code.dblock.org/github-hacked-things-to-do-on-monday</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/321</guid>
      </item>
     
      <item>
       <title>Waffle @ NYJavaSIG</title>
       <pubDate>Fri, 24 Feb 2012 00:54:01 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Waffle is a native C# and Java library that does everything Windows authentication (Negotiate, NTLM and Kerberos), on Windows - <a href="http://waffle.codeplex.com/">http://waffle.codeplex.com/</a>.</p>  <p>Slides from my presentation <a href="http://www.slideshare.net/dblockdotorg/waffle-windows-authentication-in-java">here</a>.</p>  <p><a href="http://www.slideshare.net/dblockdotorg/waffle-windows-authentication-in-java"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=430&ShowThumbnail=false" width="260" height="162" /></a></p>  <p>Oh, and yes, if you’re still writing JNI code, stop and switch to <a href="http://github.com/twall/jna">JNA</a>.</p></stripped></div><div><a href="http://code.dblock.org/waffle-nyjavasig">Read</a></div></html>
         ]]>
       </description>
       <category>appsecinc</category><category>waffle</category><category>security</category><category>active directory</category><category>win32</category>
       <link>http://code.dblock.org/waffle-nyjavasig</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/320</guid>
      </item>
     
      <item>
       <title>Watching Rack Application Changes with Guard-Rack</title>
       <pubDate>Thu, 23 Feb 2012 16:29:49 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>One of the frequently requested features in Grape to to automatically reload code changes, much like Rails does (<a href="https://github.com/intridea/grape/issues/131">#131</a>). This is actually pretty difficult to implement and requires Grape support where an <em>API::reload!</em> method would blow away all of the mounted features, procs, settings, etc.</p>  <p>For bare Rack-mounted applications we can make our life easy with Guard. Introducing <a href="https://github.com/dblock/guard-rack">guard-rack</a>, which will <em>rackup</em> your Rack application on change. On a decent developer box this just takes a second or two.  The implementation is heavily inspired (aka stolen) from <a href="https://github.com/guard/guard-rails">guard-rails</a>.</p>  <p>For a typical Rack application, including one that uses Grape, add <em>guard</em>, <em>guard-bundler</em> (to watch <em>Gemfile</em> changes) and <em>guard-rack</em> to Gemfile.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>group :development do</li> <li class="even">  gem "guard"</li> <li>  gem "guard-bundler"</li> <li class="even">  gem "guard-rack"</li> <li>end</li> </ol> </div> </div> </div>  <p>Create a <em>Guardfile</em>. Watch the folders of your application.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>guard 'bundler' do</li> <li class="even">  watch('Gemfile')</li> <li>end</li> <li class="even"> </li> <li>guard 'rack' do</li> <li class="even">  watch('Gemfile.lock')</li> <li>  watch(%r{^(config|app|api)/.*})</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>Run with <em>bundle exec guard</em>. Watch <em>rackup</em> happen every time you change files.</p>  <p>I’ve added this to my <a href="https://github.com/dblock/grape-on-rack">grape-on-rack</a> demo.</p></stripped></div><div><a href="http://code.dblock.org/watching-rack-application-changes-with-guard-rack">Read</a></div></html>
         ]]>
       </description>
       <category>rack</category><category>grape</category><category>rails</category><category>ruby</category><category>open source</category>
       <link>http://code.dblock.org/watching-rack-application-changes-with-guard-rack</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/319</guid>
      </item>
     
      <item>
       <title>Grape API Mounted on RACK w/ Static Pages, Tests, JQuery UI, Backbone.js and Even Mongo</title>
       <pubDate>Wed, 22 Feb 2012 14:19:57 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>Expanding from my <a href="http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages">previous post</a> on a Grape API mounted on RACK.</p>  <p><strong>Refactoring the Application Instance</strong></p>  <p>Instead of sticking all of the Rack application code into <em>config.ru</em>, lets build a cleaner <em>Acme::App </em>(in <a href="https://github.com/dblock/grape-on-rack/blob/master/app/acme_app.rb">app/acme_app.rb</a>). We’re going to drop <em>Rack::TryStatic</em> and build this logic ourselves, since we might need to deal with other error codes than 404 (depending on your URL strategy you may be tripping over a 405). The logic remains the same: we try a bunch of static files and delegate to the API otherwise. You can also build primitive routing instead, so that everything requesting <em>/api</em> goes to the API and everything else goes to <em>Rack::Static</em>. Your mileage will vary.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>module Acme</li> <li class="even">  class App</li> <li>    def initialize</li> <li class="even">      @filenames = [ '', '.html', 'index.html', '/index.html' ]</li> <li>      @rack_static = ::Rack::Static.new(</li> <li class="even">        lambda { [404, {}, []] }, {</li> <li>          :root =&gt; File.expand_path('../../public', __FILE__),</li> <li class="even">          :urls =&gt; %w[/]</li> <li>        })</li> <li class="even">    end</li> <li>    def call(env)</li> <li class="even">      request_path = env['PATH_INFO']      </li> <li>      # static files</li> <li class="even">      @filenames.each do |path|</li> <li>        response = @rack_static.call(env.merge({'PATH_INFO' =&gt; request_path + path}))</li> <li class="even">        return response if response[0] != 404</li> <li>      end</li> <li class="even">      # api</li> <li>      Acme::API.call(env)</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p><strong>RSpec API Tests</strong></p>  <p>Now that we have an application class, we can add API and Capybara integration tests. We start with RSpec and Rack test gems in <em>Gemfile</em>. </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; max-height: 500px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>group :test do</li> <li class="even">  gem "rspec"</li> <li>  gem "rack-test"</li> <li class="even">  gem "rspec-core"</li> <li>  gem "rspec-expectations"</li> <li class="even">  gem "rspec-mocks"</li> <li>end</li> </ol> </div> </div> </div>  <p>The <em>spec/spec_helper.rb</em> adds Rack::Test.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require 'rubygems'</li> <li class="even"> </li> <li>ENV["RACK_ENV"] ||= 'test'</li> <li class="even"> </li> <li>require 'rack/test'</li> <li class="even"> </li> <li>require File.expand_path("../../config/environment", __FILE__)</li> <li class="even"> </li> <li>RSpec.configure do |config|</li> <li class="even">  config.mock_with :rspec</li> <li>  config.expect_with :rspec</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>Testing an API involves making requests on the Rack application, pretty straightforward.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require 'spec_helper'</li> <li class="even"> </li> <li>describe Acme::API do</li> <li class="even">  include Rack::Test::Methods</li> <li> </li> <li class="even">  def app</li> <li>    Acme::API</li> <li class="even">  end</li> <li>    </li> <li class="even">  context "v1" do</li> <li>    context "system" do</li> <li class="even">      it "ping" do</li> <li>        get "/api/v1/system/ping"</li> <li class="even">        last_response.body.should == { :ping =&gt; "pong" }.to_json</li> <li>      end</li> <li class="even">    end</li> <li>  end</li> <li class="even"> </li> <li>end</li> </ol> </div> </div> </div>  <p><strong>RSpec Capybara Integration Tests</strong></p>  <p>Notice that in the tests above we’re mounting the Rack application and making requests directly to it. Does it actually work in a browser? Do we see the <em>public/index.html</em> page?</p>  <p>We start by adding capybara into Gemfile. At the time of the writing we need to use the code from Capybara head, since it adds support for <em>Capybara.app</em>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>group :test do</li> <li class="even">  gem "capybara", :git =&gt; "https://github.com/jnicklas/capybara.git"</li> <li>end</li> </ol> </div> </div> </div>  <p>The <em>spec/spec_helper.rb</em> requires <em>capybara/rspec</em>, which brings in methods like <em>page.visit</em> and assigns an instance of the application to <em>Capybara.app</em>. Capybara will launch the application for us.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require 'capybara/rspec'</li> <li class="even">Capybara.configure do |config|</li> <li>  config.app = Acme::App.new</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>An integration test can go into <em>spec/integration</em> and must be marked with <em>request: true </em>and <em>js: true</em> (the latter forces the use of the Selenium driver that will popup a browser). Lets look for a proper title on the homepage.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require 'spec_helper'</li> <li class="even"> </li> <li>describe "Grape on RACK", :js =&gt; true, :type =&gt; :request do</li> <li class="even">  context "homepage" do</li> <li>    before :each do</li> <li class="even">      visit "/"</li> <li>    end</li> <li class="even">    it "displays index.html page" do</li> <li>      page.find("title").text.should == "Rack Powers Web APIs"</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p><strong>A POST, PUT and Some JQuery</strong></p>  <p>The sample source in <a href="https://github.com/dblock/grape-on-rack">https://github.com/dblock/grape-on-rack</a> also adds JQuery, extends the API to simulate a persisted counter, and makes PUT requests to it. Complete with an integration test. Run <em>bundle install</em> and <em>bundle exec rackup </em>to see it and <em>bundle exec rspec spec</em> to run the tests.</p>  <p><strong>Backbone.js w/ Mongo</strong></p>  <p><a href="https://github.com/knewter">@knewter</a> put together a neat Backbone.js + MongoDB w/ Mongoid demo using Grape that is built in a similar manner, <a href="https://github.com/knewter/grape_demo">https://github.com/knewter/grape_demo</a>. </p></stripped></div><div><a href="http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages-tests-jquery-ui-backbonejs-and-even-mongo">Read</a></div></html>
         ]]>
       </description>
       <category>rack</category><category>mongoid</category><category>jquery</category><category>javascript</category><category>grape</category>
       <link>http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages-tests-jquery-ui-backbonejs-and-even-mongo</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/318</guid>
      </item>
     
      <item>
       <title>Don’t Hate UI Testing - Reliably Testing Asynchronous UI w/ RSpec &amp; Capybara</title>
       <pubDate>Sun, 12 Feb 2012 17:00:05 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><a href="http://code.dblock.org/ShowPicture.aspx?id=426&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="capybara4-510x394" border="0" alt="capybara4-510x394" src="http://code.dblock.org/ShowPicture.aspx?id=427&ShowThumbnail=false" width="244" height="189" /></a></p>  <p><font size="1">(this Capybara is quite sure of himself, photo from </font><a href="http://www.cuteandweird.com/2010/10/capybara-pictures-caplin-the-giant-rodent/"><font size="1">here</font></a><font size="1">)</font></p>  <p>Last week I wrote <a href="http://artsy.github.com/blog/2012/02/03/reliably-testing-asynchronous-ui-w-slash-rspec-and-capybara/">an article on the Art.sy Enginering blog about testing with RSpec and Capybara</a>. </p>  <p>This wasn’t the first time I dealt with UI testing. And I am definitely getting a hang of it. I believe it goes in hand with the fact that I detest using mocks in tests and prefer to test the real thing. Sacrificing test purity for better coverage is better, IMHO.</p>  <p>I’ve done quite a bit of Win32 UI testing: read <a href="http://code.dblock.org/automating-win32-ui-testing-systemwindowsautomation-and-project-white">this post</a>. In fact, the entire dotNetInstaller InstallEditor test suite manipulates UI – check out the <a href="http://dotnetinstaller.codeplex.com/SourceControl/changeset/view/70081#801450">source of this test</a>. For the anecdote I was writing a DNI feature on the Subway and the guy sitting next to me looked at my computer as if it were possessed. He proceeded telling me a story about how he thought his computer was hijacked, what the best Anti-Virus was and how he got rid of unusual Windows problems. He was incredible and spoke with great passion. I gave him my card and asked him to come and give a motivational talk on the topic of “computers have a life of their own”. Too bad he never did.</p>  <p>I’ve done a bit of GWT UI testing with Selenium. That was a major pain. Capybara definitely takes a lot of that pain away.</p>  <p>I know the test automation community is always complaining about brittle and slow tests that involve a real browser. I refuse to be a hater – UI test automation, otherwise known as <em>integration testing</em>, has saved my product’s behind many, many times.</p></stripped></div><div><a href="http://code.dblock.org/dont-hate-ui-testing-reliably-testing-asynchronous-ui-w-rspec-capybara">Read</a></div></html>
         ]]>
       </description>
       <category>rspec</category><category>selenium</category><category>capybara</category><category>testing</category><category>dotnetinstaller</category>
       <link>http://code.dblock.org/dont-hate-ui-testing-reliably-testing-asynchronous-ui-w-rspec-capybara</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/316</guid>
      </item>
     
      <item>
       <title>Toyota Production System &amp; Why Should Architects Write Code</title>
       <pubDate>Sun, 12 Feb 2012 16:05:14 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><a href="http://code.dblock.org/ShowPicture.aspx?id=428&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="toyota" border="0" alt="toyota" src="http://code.dblock.org/ShowPicture.aspx?id=429&ShowThumbnail=false" width="244" height="163" /></a></p>  <p>I recently read <a href="http://astro.temple.edu/~rmudambi/Teaching/BA951/Week_04/Toyota-Darker-Side-Mehri.pdf">“The Darker Side of Lean”</a> by Darius Mehri. It is a fascinating account of the evil aspects of the much celebrated Toyota Production System. The author of the paper is a mechanical engineer. Yet, the way he describes Japanese approach to choosing technology struck me as déjà vu.</p>  <blockquote>   <p><em>To arrive at the best design, the engineers would gather huge amounts of information, comparing new designs with previous designs. If the technology unearthed by their research could benefit the product in any way, they would include it in the many alternatives they were considering. Sobek, Ward and Liker’s research compare Toyota’s approach to product development as set-based design where “designers think and reason about sets of design alternatives. Over time, these sets are gradually narrowed as the designers eliminate inferior alternatives until they find a final solution.” They claim this method differs from the conventional practice of choosing a single design early on and iterating to improve it until a solution is obtained.</em></p> </blockquote>  <p>We often think of software architects as experienced developers whose job is to consider all aspects of a future system, including scalability and performance. At extremes this causes architects to lock themselves in a room for days and think about all possible alternatives by making long lists or drawing endless architecture diagrams. Vendors are invited and feature matrices are compared. It’s a very similar process to the one described in this paper, heavily adopted by the Enterprise.</p>  <p>A simple solution is to ensure that architects write code, at least 40% of their time. This forces us to “<em>choose a single design early and iterate to improve it”</em>. The consequences are felt first hand. And when we feel pain with our own skin, we know when it’s time to throw out a component, technology or system and when to go back to the drawing board.</p></stripped></div><div><a href="http://code.dblock.org/toyota-production-system-why-should-architects-write-code">Read</a> | Updated 2/13/2012</div></html>
         ]]>
       </description>
       <category>technology</category><category>architecture</category>
       <link>http://code.dblock.org/toyota-production-system-why-should-architects-write-code</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/317</guid>
      </item>
     
      <item>
       <title>Updating Devise Trackable Last User Sign-In Time with Devise Rememberable</title>
       <pubDate>Wed, 08 Feb 2012 15:48:07 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><a href="https://github.com/plataformatec/devise">Devise</a> has a <em>:trackable </em>strategy which updates the user’s last sign-in time, remote IP and increments a counter in the <em>User</em> model upon successful logon. This is implemented in <a href="https://github.com/plataformatec/devise/blob/master/lib/devise/models/trackable.rb">Devise::Models::Trackable.update_tracked_fields!</a> and invoked as a Warden callback in <a href="https://github.com/plataformatec/devise/blob/master/lib/devise/hooks/trackable.rb">devise/hooks/trackable.rb</a>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; max-height: 100px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>Warden::Manager.after_set_user :except =&gt; :fetch do |record, warden, options|</li> <li class="even">  if record.respond_to?(:update_tracked_fields!) && warden.authenticated?(options[:scope]) && !warden.request.env['devise.skip_trackable']</li> <li>    record.update_tracked_fields!(warden.request)</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>  <p>Warden will invoke the callback every time <em>warden.set_user</em> is called, which is done once per logon with <em>:event =&gt; :authenticate</em> in the options. But when used with the <em>:rememberable</em> strategy, a returning user is not logging on – he continues a previous session. The callback is invoked with an <em>:event =&gt; :fetch</em> in the options, which is explicitly excluded in the code above.</p>  <p>Of course, we might not see things in the same eye. A user returning 24 hours later might as well be logging in again. Lets add a callback that will update tracked fields in this case (to <em>config/initializers/devise_trackable.rb</em>).</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>Warden::Manager.after_set_user do |record, warden, options|</li> <li class="even">  if record.respond_to?(:update_tracked_fields!) && warden.authenticated?(options[:scope]) && ! warden.request.env['devise.skip_trackable'] &&</li> <li>    (record.last_sign_in_at.nil? || (Date.today - record.last_sign_in_at.to_date).to_i &gt;= 1)</li> <li class="even">    record.update_tracked_fields!(warden.request)</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>Is there a better way to do this? Maybe something worth contributing in one way or another to Devise?</p></stripped></div><div><a href="http://code.dblock.org/updating-devise-trackable-last-user-sign-in-time-with-devise-rememberable">Read</a></div></html>
         ]]>
       </description>
       <category>devise</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/updating-devise-trackable-last-user-sign-in-time-with-devise-rememberable</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/315</guid>
      </item>
     
      <item>
       <title>Jenkins AnsiColor 0.2.1 w/ Support for Conceal Codes</title>
       <pubDate>Fri, 03 Feb 2012 13:26:50 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I just released <a href="https://wiki.jenkins-ci.org/display/JENKINS/AnsiColor+Plugin">AnsiColor 0.2.0</a> that now supports the ANSI conceal code. Conceal code 0x8 is a hacky way to hide data inside text using ANSI sequences. Jenkins uses it to annotate output with something that looks like <em>ha:&lt;long base64 string&gt;</em>. You can see this implemented in <a href="https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/console/ConsoleNote.java">ConsoleNote.java</a>. The previous version of AnsiColor produced garbage by stripping the conceal sequence, therefore revealing the content inside the conceal block (<a href="https://github.com/dblock/jenkins-ansicolor-plugin/issues/3">issue #3</a>). Fixed in <a href="https://github.com/dblock/jenkins-ansicolor-plugin/commit/c804caf8f1f785a0bd0eaf47f231a1f22b8b0356">this commit</a>. Also updated <a href="http://jansi.fusesource.org/">Jansi</a> to 1.7 – Jansi makes this plugin possible.</p>  <p>Update your Jenkins.</p></stripped></div><div><a href="http://code.dblock.org/jenkins-ansicolor-021-w-support-for-conceal-codes">Read</a></div></html>
         ]]>
       </description>
       <category>jenkins</category><category>java</category>
       <link>http://code.dblock.org/jenkins-ansicolor-021-w-support-for-conceal-codes</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/314</guid>
      </item>
     
      <item>
       <title>CarrierWave: DelayJob-Processing of Selected Versions, Revisited</title>
       <pubDate>Tue, 31 Jan 2012 14:26:52 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>I’ve written about delay-processing certain image versions in <a href="http://code.dblock.org/carrierwave-delayjob-processing-of-selected-versions">this article</a>. We’ve made some progress since with a much more robust implementation. Check out <a href="http://artsy.github.com/blog/2012/01/31/delaying-carrierwave-image-processing/">this new post</a> on the Art.sy Engineering blog.</p></stripped></div><div><a href="http://code.dblock.org/carrierwave-delayjob-processing-of-selected-versions-revisited">Read</a></div></html>
         ]]>
       </description>
       <category>carrierwave</category><category>rails</category><category>ruby</category>
       <link>http://code.dblock.org/carrierwave-delayjob-processing-of-selected-versions-revisited</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/313</guid>
      </item>
     
      <item>
       <title>Testing w/ Analytical Gem and RSpec</title>
       <pubDate>Mon, 30 Jan 2012 21:07:14 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p>We use the <a href="https://github.com/jkrall/analytical">Analytical</a> gem to include various thirdparty Javascripts in our Rails application. Our test environment was configured with dummy values in <em>config/analytical.yml</em>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>production:</li> <li class="even">  google:</li> <li>    key: &lt;%= ENV['GOOGLE_UA'] %&gt;</li> <li class="even">  kiss_metrics:</li> <li>    js_url_key: &lt;%= ENV['KISS_METRICS_URL_KEY'] %&gt;</li> <li class="even"> </li> <li>test:</li> <li class="even">  google:</li> <li>    key: 'UA-12345'</li> <li class="even">  kiss_metrics:</li> <li>    js_url_key: 12345</li> <li class="even"> </li> <li>development:</li> </ol> </div> </div> </div>  <p>We wrote a few simple tests to make sure the analytical code is being included properly. For example, we can check whether Google Analytics is included on the splash page.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>context "google analytics" do</li> <li class="even">  it "should appear on the splash page" do</li> <li>    visit "/"</li> <li class="even">    within :css, "script[type='text/javascript']:contains('.google-analytics.com/')" do</li> <li>      page.should have_content("UA-12345")</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>  <p>Or, more complicated, test whether a user ID is sent to Kissmetrics.</p>  <p>   </p><div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>context "kiss-metrics analytics" do</li> <li class="even">  it "should appear on the splash page" do</li> <li>    visit "/"</li> <li class="even">    within :css, "script[type='text/javascript']:contains('kissmetrics.com/')" do</li> <li>      page.should have_content("12345")</li> <li class="even">    end</li> <li>  end</li> <li class="even">  context "logged-in user" do</li> <li>    before(:each) do</li> <li class="even">      login_as @user</li> <li>      visit "/"</li> <li class="even">    end</li> <li>    it "should appear on the search page" do</li> <li class="even">      within :css, "script[type='text/javascript']:contains('kissmetrics.com/')" do</li> <li>        page.should have_content("12345")</li> <li class="even">      end</li> <li>    end</li> <li class="even">    it "should include user id" do</li> <li>      within :css, "script[type='text/javascript']:contains(\"identify\")" do</li> <li class="even">        page.should have_content("[\"identify\", \"#{@user.id}\"]);")</li> <li>      end</li> <li class="even">    end</li> <li>  end</li> <li class="even">end</li> </ol> </div> </div> </div>   <p>The drawback of this approach is that the Analytical code is included with every other test that doesn’t need it. With every Capybara test that runs in a browser, this hits DNS, then makes an HTTP request to Google and Kissmetrics. We cannot stub that with VCR or another gem because we’re using a real browser. But we can selectively enable Analytics without a configuration file by emptying the <em>:test</em> block in <em>config/analytical.yml </em>by configuring it before any test that needs it.</p>      <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>before :each do</li> <li class="even">    @analytical_options = ApplicationController.analytical_options.dup</li> <li>    ApplicationController.analytical_options = @analytical_options.merge({ </li> <li class="even">        :modules =&gt; [ :google, :kiss_metrics ],</li> <li>        :google =&gt; { :key =&gt; "UA-12345" },</li> <li class="even">        :kiss_metrics =&gt; { :js_url_key =&gt; 12345 }</li> <li>    })</li> <li class="even">end</li> <li>after :each do</li> <li class="even">    ApplicationController.analytical_options = @analytical_options</li> <li>end</li> </ol> </div> </div> </div>  <p>It helps to be open-source. Looking at the internals of Analytical, its options are processed inside each controller on load, then merged with request options on every request before anything is rendered. The code above updates the configuration between those two steps. Note that since we’re modifying a static we have to make sure to cleanup after ourselves.</p></stripped></div><div><a href="http://code.dblock.org/testing-w-analytical-gem-and-rspec">Read</a></div></html>
         ]]>
       </description>
       <category>rails</category><category>ruby</category><category>testing</category>
       <link>http://code.dblock.org/testing-w-analytical-gem-and-rspec</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/312</guid>
      </item>
     
      <item>
       <title>Grape API Mounted on RACK w/ Static Pages</title>
       <pubDate>Mon, 30 Jan 2012 15:54:46 GMT</pubDate>
       <description>
         <![CDATA[
          <!--[if lt IE 7 ]><html class="ie ie6" lang="en"> <![endif]-->
          <!--[if IE 7 ]><html class="ie ie7" lang="en"> <![endif]-->
          <!--[if IE 8 ]><html class="ie ie8" lang="en"> <![endif]-->
          <!--[if (gte IE 9)|!(IE)]><!--><html lang="en"> <!--<![endif]-->
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/base.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/skeleton.css" />
          <link rel="stylesheet" href="http://code.dblock.org/stylesheets/layout.css" />
          <link rel="apple-touch-icon" href="http://code.dblock.org/images/apple-touch-icon.png" />
          <link rel="apple-touch-icon" sizes="72x72" href="http://code.dblock.org/images/apple-touch-icon-72x72.png" />
          <link rel="apple-touch-icon" sizes="114x114" href="http://code.dblock.org/images/apple-touch-icon-114x114.png" />
          <html><div><stripped><p><em>tl;dr</em> – the source is <a href="https://github.com/dblock/grape-on-rack">here</a></p>  <p>Here’s how I mount a <a href="http://github.com/intridea/grape">Grape</a> API on Rack and also serve static pages. Most useful for building a service with documentation.</p>  <p>Setup bundler with the required gems. I am using the next version of Grape (<em>frontier</em> branch and the next version of <em>rack-contrib</em> which contains <em>Rack::TryStatic </em>that we’re going to want to use). </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>source "http://rubygems.org"</li> <li class="even"> </li> <li>gem "rack", "1.3.5"</li> <li class="even">gem "rack-contrib", :git =&gt; "https://github.com/rack/rack-contrib.git", :require =&gt; "rack/contrib"</li> <li>gem "grape", :git =&gt; "http://github.com/intridea/grape.git", :branch =&gt; "frontier"</li> </ol> </div> </div> </div>  <p>Static content goes to a new <em>public</em> folder, for example <em>public/index.html</em>.</p>  <p>Our application will need to boot with all these gems, we’ll do it Rails-style by starting with a <em>config/boot.rb</em> file. It brings in Bundler.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require 'rubygems'</li> <li class="even">require 'bundler/setup'</li> </ol> </div> </div> </div>  <p>Lets define our Acme Grape API that will have a <em>system</em> resource that answers <em>ping</em> requests with <em>“pong”. </em>This<em> </em>goes into <em>api/api.rb.</em></p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; max-height: 300px; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>module Acme</li> <li class="even">  class API &lt; Grape::API</li> <li>    version 'v1', :using =&gt; :header, :vendor =&gt; 'acme', :format =&gt; :json    </li> <li class="even">    resource :system do</li> <li>      desc "Returns pong."</li> <li class="even">      get :ping do</li> <li>        "pong"</li> <li class="even">      end</li> <li>    end</li> <li class="even">  end</li> <li>end</li> </ol> </div> </div> </div>  <p>The application requires Bundler, all the gems in Gemfile and our API. Lets define it in <em>config/application.rb</em>.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require File.expand_path('../boot', __FILE__)</li> <li class="even"> </li> <li>Bundler.require :default, ENV['RACK_ENV']</li> <li class="even"> </li> <li>require File.expand_path('../../api/api', __FILE__)</li> </ol> </div> </div> </div>  <p>Note the odd <em>File.expand_path</em> construct, borrowed from Rails, - it translates a relative path to the current file into an absolute path, there’re allowing us to run the application from any directory – useful for hosting where you never know who boots the application.</p>  <p>Continuing to borrow from Rails, we will want different environments (development, production, etc.), so it’s a good idea to keep things organized. Setup the environment in <em>config/environment.rb </em>and then load the application. </p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>ENV['RACK_ENV'] ||= :test</li> <li class="even"> </li> <li>require File.expand_path('../application', __FILE__)</li> </ol> </div> </div> </div>    <p>Finally, we need to “rackup” this whole thing in <em>config.ru</em>. We will use <em>Rack::TryStatic</em> to serve static pages when available and pass through to the Acme API otherwise.</p>  <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" class="wlWriterEditableSmartContent"> <div class="le-pavsc-container"> <div style="background: #fff; overflow: auto"> <ol style="background: #ffffff; margin: 0; padding: 0 0 0 5px;"> <li>require File.expand_path('../config/environment', __FILE__)</li> <li class="even"> </li> <li>use Rack::TryStatic, </li> <li class="even">  :root =&gt; File.expand_path('../public', __FILE__), </li> <li>  :urls =&gt; %w[/], :try =&gt; ['.html', 'index.html', '/index.html']</li> <li class="even"> </li> <li>run Acme::API</li> </ol> </div> </div> </div>  <p>Run the application with <em>bundle exec rackup</em>.</p>  <p><a href="http://code.dblock.org/ShowPicture.aspx?id=424&ShowThumbnail=false"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://code.dblock.org/ShowPicture.aspx?id=425&ShowThumbnail=false" width="640" height="272" /></a></p>  <p>Full <a href="https://github.com/dblock/grape-on-rack">source on Github</a>.</p></stripped></div><div><a href="http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages">Read</a></div></html>
         ]]>
       </description>
       <category>rack</category><category>grape</category><category>ruby</category>
       <link>http://code.dblock.org/grape-api-mounted-on-rack-w-static-pages</link>
       <guid isPermaLink="false">http://code.dblock.org/Post/311</guid>
      </item>
         
  </channel>
</rss>

