<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>Pathfinder Software &#187; John McCaffrey</title> <atom:link href="http://pathfindersoftware.com/author/john-mccaffrey/feed/" rel="self" type="application/rss+xml" /><link>http://pathfindersoftware.com</link> <description>The Fastest Way to Launch Successful Software</description> <lastBuildDate>Thu, 19 Jan 2012 16:31:04 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>What is the ideal Senior Developer skillset?</title><link>http://pathfindersoftware.com/2009/11/ideal-senior-developer-skillset/</link> <comments>http://pathfindersoftware.com/2009/11/ideal-senior-developer-skillset/#comments</comments> <pubDate>Wed, 11 Nov 2009 22:21:53 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Ruby on Rails]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[assembla]]></category> <category><![CDATA[blog]]></category> <category><![CDATA[career]]></category> <category><![CDATA[developer]]></category> <category><![CDATA[development]]></category> <category><![CDATA[Interview]]></category> <category><![CDATA[job]]></category> <category><![CDATA[Open Source]]></category> <category><![CDATA[rails]]></category> <category><![CDATA[ruby]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=4335</guid> <description><![CDATA[We&#8217;re currently in the process of interviewing candidates for 1-2 Senior, and 2-3 junior level Rails Developers, and I&#8217;m wondering about the skills that are most critical, and how best to identify the best candidates. My normal interview process flows like this: Quick Phone screen evaluating basic development skills, background, availability, personality Basic coding problem ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><div class="right"> <a href="http://www.pathf.com/blogs/wp-content/uploads/2009/11/IMGP3922.JPG" target="_blank"><img class="alignright size-full wp-image-4339" title="IMGP3922" src="http://www.pathf.com/blogs/wp-content/uploads/2009/11/IMGP3922.JPG" alt="IMGP3922" width="368" height="257" /></a></div><p>We&#8217;re currently in the process of interviewing candidates for 1-2 Senior, and 2-3 junior level Rails Developers, and I&#8217;m wondering about the skills that are most critical, and how best to identify the best candidates.</p><p>My normal interview process flows like this:</p><ol><li>Quick Phone screen evaluating basic development skills, background, availability, personality</li><li>Basic coding problem (less than 1hr to complete)</li><li>Phone call to review coding problem, &#8216;how would you handle X?&#8217; questions, etc</li><li>On site interview targeting: Communication, Communication, Communication, (and tech)</li><li>Final decision</li></ol><p>Independent of the language they will be working with, I&#8217;ve found decent success with having candidates answer some standard dev questions, solve a basic coding problem, and demonstrate their ability to whiteboard a design.</p><p>The problem is that it doesn&#8217;t scale. When we&#8217;ve opened up positions in the past, either Senior or Junior, there have been so many applications that its hard to contact them all. This leads to a reshuffling of the tasks and matching criteria, in an attempt to identify the &#8216;best&#8217; matches, and &#8216;filter out&#8217; the others.  So instead of calling each candidate first, we might simply reply to them with the details of the coding assignment. I&#8217;ve seen 40 people send the &#8220;I&#8217;m an extremely hard worker, very interested in your position and would do anything to join your wonderful company&#8221; cover letter and resume, and then get whittled down to only 10 candidates that actually submit the assignment.  (Note to applicants: &#8216;showing up&#8217; is an important first step!)</p><p>I came across an interesting post titled <a title="11 tips on hiring a rails developer" href="http://www.rubyinside.com/11-tips-on-hiring-a-rails-developer-662.html" target="_blank">&#8217;11 tips on hiring a rails developer&#8217;</a> which mentioned some &#8216;filtering&#8217; criteria to identify the best candidates</p><p>You can read the full description of each one, but there are a few of these that I wanted to highlight:</p><ol><li><strong><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Don&#8217;t use Monster.com or recruitment agencies.</span></strong></li><li><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Poach Talent from other companies!<br /> </span></li><li><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Don&#8217;t hire someone that doesn&#8217;t know Rails at all.</span></li><li><strong><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Look for open source contributions.</span></strong></li><li><strong><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">A personal Rails blog is required.</span></strong></li><li><strong><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">A university degree is not important.</span></strong></li><li><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Be wary of holes in proficiency.</span></li><li><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Avoid brand-name superstars.</span></li><li><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Hire perpetually.</span></li><li><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Have a company Rails blog</span></li><li><strong><span style="font-family: 'Lucida Grande',Verdana,Helvetica,Arial; font-size: 13px; line-height: 20px; text-align: left;">Special compensation.</span></strong></li></ol><p>So each of these tips is meant as a heuristic or proxy of the true underlying ability. Any time you are making generalizations you are going to miss out on a few exceptions, but hopefully you end up with what you are looking for.</p><p>Starting with the most controversial first, <strong>(#5) </strong> while I like the idea of giving a strong preference to someone that has a rails blog, and loves  Ruby, Rails, and Web Development enough to be opinionated and spend their own time ranting about it, I&#8217;m not sure I could make it a filtering criteria. Doesn&#8217;t that seem a bit strong?</p><p>I feel the same about<strong> (#4)</strong> Open Source contribution. I think its great if they have it, but I&#8217;m not sure I would reject any candidates that haven&#8217;t contributed to open source.</p><p>While I&#8217;ve met many systems administrators that <strong>(#6)</strong> don&#8217;t have a degree, and are very good at their craft, I haven&#8217;t really encountered many solid developers that don&#8217;t have a degree. That&#8217;s not to say they aren&#8217;t out there, I&#8217;m just saying I&#8217;ve never encountered them, and I&#8217;m reluctant to use it as a filter. Do you think that there are many strong Rails developers out there without degrees? (I don&#8217;t care if they  have a CS degree, but I think I prefer that they have some kind of degree)</p><p>As it relates to <strong>(#1)</strong> and<strong> (#11)</strong>, I know for sure that the economics of finding a candidate through your own network and contacts can be less expensive than the recruiter fees (assuming you find a decent candidate and don&#8217;t waste a lot of your own time doing it), and if you are able to find someone directly, it frees up cash for such amenities as &#8216;New Macbook Pro&#8217;, &#8216;RailsConf&#8217;, and &#8216;Fridge full of XXX&#8217;.</p><h4>If I was in charge of everything</h4><p>I really like what <a href="http://blog.jonudell.net/2009/02/09/a-conversation-with-andy-singleton-about-distributed-software-development/" target="_blank">Andy Singleton</a> describes regarding how his team at <a href="http://www.assembla.com" target="_blank">Assembla</a> is organized and tackles Agile Development, and on the right project, I&#8217;d really like take his advice and try this one:</p><p>&#8220;<span style="color: #29303b; font-family: Georgia,Verdana,Arial,serif; font-size: 12px; line-height: 18px; text-align: left;"><strong>Don’t interview</strong>. Just pay people to join a project, pull a task from the queue, and find out what they can do.&#8221;</span></p><p><span style="color: #29303b; font-family: Georgia,Verdana,Arial,serif; font-size: 12px; line-height: 18px; text-align: left;">Anyways,  I&#8217;d be very interested in your thoughts regarding what makes for a Solid Rails developer, where you find them, how you keep them, and what you&#8217;ve learned.</span></p><p><span style="color: #29303b; font-family: Georgia,Verdana,Arial,serif; font-size: 12px; line-height: 18px; text-align: left;">(Oh, and if you know any passionate Rails Developers in the Chicago area, send them over!)<br /> </span><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;linkname=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;linkname=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;linkname=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;linkname=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;linkname=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;linkname=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;linkname=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F11%2Fideal-senior-developer-skillset%2F&amp;title=What%20is%20the%20ideal%20Senior%20Developer%20skillset%3F" id="wpa2a_2">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/11/ideal-senior-developer-skillset/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Rails DateTime.to_time, Time, and a case of &#039;Why do you need to do that?&#039;</title><link>http://pathfindersoftware.com/2009/09/rails-datetimetotime-time-case-why-that/</link> <comments>http://pathfindersoftware.com/2009/09/rails-datetimetotime-time-case-why-that/#comments</comments> <pubDate>Wed, 23 Sep 2009 19:24:07 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Ruby on Rails]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[CI]]></category> <category><![CDATA[date]]></category> <category><![CDATA[datetime]]></category> <category><![CDATA[Hudson]]></category> <category><![CDATA[LINUX]]></category> <category><![CDATA[os]]></category> <category><![CDATA[rails]]></category> <category><![CDATA[ruby]]></category> <category><![CDATA[Testing]]></category> <category><![CDATA[time]]></category> <category><![CDATA[timezone]]></category> <category><![CDATA[Windows]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=4076</guid> <description><![CDATA[The problem: I needed to display a warning to a user if the data they were looking at was more than 90 days old. The solution: Create a method that takes 2 dates (either DateTime or Time), and returns the number of days, or hours between them. def self.difference_in_dates(date1, date2, unit = 1.day) return nil ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><div class="right"><a href="http://pathfindersoftware.com/wp-content/uploads/balboa_clock1.jpg"><img class="alignright size-full wp-image-4176" title="balboa_clock" src="http://pathfindersoftware.com/wp-content/uploads/balboa_clock1.jpg" alt="balboa_clock" width="536" height="382" /></a></div><p><strong>The problem</strong>:  I needed to display a warning to a user if the data they were looking at was more than 90 days old.</p><p><strong>The solution</strong>:  Create a method that takes 2 dates (either DateTime or Time), and returns the number of days, or hours between them.</p><pre lang="ruby">  def self.difference_in_dates(date1, date2, unit = 1.day)
    return nil if date1.nil? || date2.nil? || unit == 0
      (( date1.to_time - date2.to_time ) / unit).round.abs
  end</pre><p>The problem was simple enough, and my tests were all passing, so I moved on to my next task.</p><p>That code has been out in production for several months, but earlier this week, a new developer told me he got an error when running the test:</p><pre>  NoMethodError: undefined method `to_f'
    for Mon, 21 Sep 2009 14:29:38 -0500:DateTime</pre><p>(we&#8217;re running this in Rails 2.0.2)</p><p>I looked at the code, knowing it was working before, ran the unit tests myself, and didn&#8217;t see the issue. Now I&#8217;m on Windows and everyone else is on a mac, so as soon as I run into an issue that no one else has seen I want to prove if its a Windows problem. But wait, this test has been running in our Continuous Integration server (Hudson) for months, and no one else on the team ever had any issues with it, and the code has been working in production without any errors in the logs.</p><p>I jumped into rails script/console to see what&#8217;s up, and here&#8217;s what I found:</p><pre lang="ruby"> >> x = DateTime.now
=> Wed, 23 Sep 2009 00:00:00 +0000
>>; x.to_time
=> Wed Sep 23 00:00:00 UTC 2009
>> x.to_time.to_f
=> 1253664000.0</pre><p>Which is what I expected, but when I asked the other developer to run that same instruction, he got an error.</p><pre>&gt;&gt; DateTime.now.to_time.to_f
NoMethodError: undefined method `to_f'
  for Mon, 21 Sep 2009 14:29:38 -0500:DateTime</pre><p>What&#8217;s up with that? We&#8217;re running the same code, and all of our libraries are the same version. Looking at the date value in his error, I saw the timezone, and decided to try this variation locally:</p><pre lang="ruby">>>  x = DateTime.parse("2009-09-21T14:29:38-0500")
=> Mon, 21 Sep 2009 14:29:38 -0500
>> x.to_time.class
=>; DateTime</pre><p>So I&#8217;m gathering that when there is a timezone and you ask DateTime.to_time, its just going to give you back a DateTime.<br /> <span id="more-4076"></span> I wasn&#8217;t expecting this, and its exactly why my code was failing, because <em>sometimes </em> the DateTime.to_time will return just a DateTime object.  The <a href="http://www.railsbrain.com/api/rails-2.0.2/doc/index.html?a=C00000045&amp;name=DateTime#" target="_blank">Rails 2.0.2 docs</a> do state this:</p><pre><strong>to_time()</strong>
Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class If self has an offset other than 0, self will just be returned unaltered, since there’s no clean way to map it to a Time</pre><p>Ok, so I guess I have no excuse, its written right there in the docs, but I guess I, didn&#8217;t really look at the docs for the to_time method, or if I did, I didn&#8217;t really get what it was telling me. Either way I have a problem that isn&#8217;t going to change.</p><p>When I asked my colleagues at Pathfinder, they all said &#8220;Why do you need to do that?&#8221; and &#8220;couldn&#8217;t you find a gem or plugin that does that already?&#8221;</p><p>Which is a solid point. If you are doing something as common as checking for the difference between two dates you should expect to see either some straight code examples of the best way to do it, or a plugin or gem that solves that problem. I&#8217;ll need to dig into this a little further, but for the moment I simply updated the code to:</p><pre lang="ruby">  def self.difference_in_dates(time1, time2, unit = 1.day)
    return nil if time1.nil? || time2.nil? || unit == 0
    (( time1 - time2)  / unit).round.abs
  end</pre><p>and I looked through the places I was using this code and made sure I only passed in a Time object, so now I&#8217;ve &#8216;fixed&#8217; the bug so that the tests don&#8217;t fail for anyone else, and I&#8217;ve bought myself some time to figure out what&#8217;s the best course of action.</p><p>But I&#8217;m still curious why DateTime.now behaves differently depending on OS? What&#8217;s going on there?<br /> I jumped on to our build server (CentOs) and ran DateTime.now, and see no timezone, and that&#8217;s why the tests don&#8217;t fail there.<br /> I jumped over to my heroku server and saw that DateTime.now includes a timezone.</p><p>Wondering what the os was I ran:</p><pre>`uname -sr`.chomp.strip
"Linux 2.6.18-xenU-ec2-v1.0"
&gt;&gt; `cat /etc/issue.net`
=&gt; "Debian GNU/Linux 4.0"</pre><p>So what dictates the Date and Time setup? Is it purely an OS thing, or is it just a component of how time is setup on the server?</p><p>I jumped over to another Debian box, and there DateTime.now doesn&#8217;t include the timezone, so now I&#8217;m thinking that its not as simple as just the OS, but something else.  (please someone, enlighten me!)</p><p><strong>Conclusion</strong>: Don&#8217;t be an idiot<br /> I did a few things wrong here, and I deserve to be flamed for it:</p><ol><li>Read the docs, understand the code you are relying on. In most cases, ruby and rails just does what you&#8217;d expect, but its still worth reading into, even when things seem to be working just fine.</li><li>If the problem you are trying to solve seems common, google around, ask others what they have done, dig into the framework, etc. Assume you aren&#8217;t the first to run into it.</li><li>If it seems that what you are doing isn&#8217;t common, or isn&#8217;t handled in the frameworks/libraries you are using, perhaps it means you are looking at the problem the wrong way and there is another, simpler solution out there.</li><li>Test your assumptions. I will say that at least I had tests that covered my assumptions, and failed when they weren&#8217;t true. I may not have written the best solution, but at least it worked on every system we deployed it to, and never failed in production</li></ol><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;linkname=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;linkname=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;linkname=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;linkname=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;linkname=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;linkname=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;linkname=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F09%2Frails-datetimetotime-time-case-why-that%2F&amp;title=Rails%20DateTime.to_time%2C%20Time%2C%20and%20a%20case%20of%20%26%23039%3BWhy%20do%20you%20need%20to%20do%20that%3F%26%23039%3B" id="wpa2a_4">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/09/rails-datetimetotime-time-case-why-that/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Chiphone Meeting: Chicago iPhone user group gets its TDD on</title><link>http://pathfindersoftware.com/2009/08/chiphone-meeting-chicago-iphone-user-group-tdd/</link> <comments>http://pathfindersoftware.com/2009/08/chiphone-meeting-chicago-iphone-user-group-tdd/#comments</comments> <pubDate>Fri, 28 Aug 2009 16:25:30 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Mobile Apps]]></category> <category><![CDATA[Ruby on Rails]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[agile]]></category> <category><![CDATA[animation]]></category> <category><![CDATA[Confluence]]></category> <category><![CDATA[Dojo]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[Mock]]></category> <category><![CDATA[ocmock]]></category> <category><![CDATA[pairing]]></category> <category><![CDATA[Pathfinder General]]></category> <category><![CDATA[rails]]></category> <category><![CDATA[randori]]></category> <category><![CDATA[tdd]]></category> <category><![CDATA[xcode]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=3816</guid> <description><![CDATA[Eric Smith from 8th light gave a hands-on TDD presentation at last night&#8217;s Chiphone meeting, hosted at Obtiva&#8217;s downtown office, (conveniently located near the the train). There was a good crowd of people, most attendees have &#8216;played around&#8217; with iphone development, 4 have actively developed apps (3 people have live apps in the store).  From my ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><div class="right"><a href="http://pathfindersoftware.com/wp-content/uploads/chiphone1.png"><img class="alignright size-full wp-image-3823" title="chiphone" src="http://pathfindersoftware.com/wp-content/uploads/chiphone1.png" alt="chiphone" width="250" height="434" /></a></div><p>Eric Smith from <a href="http://blog.8thlight.com" target="_blank">8th light</a> gave a hands-on TDD presentation at last night&#8217;s <a href="http://chiphonegroup.org/" target="_blank">Chiphone</a> meeting, hosted at Obtiva&#8217;s downtown office, (conveniently located near the the train).</p><p>There was a good crowd of people, most attendees have &#8216;played around&#8217; with iphone development, 4 have actively developed apps (3 people have live apps in the store).  From my quick survey of those that have submitted apps, it seems most of them were free utility apps or simple games, with at least one commercial app <a href="http://www.3boxed.com/dashconfluence/Dash_for_Confluence.html" target="_blank">Dash for Confluence</a>. It also seemed that no one had yet needed to do any animation beyond the basics, with just a bit of core-animation, but no need for more lower-level openGL or animation engines.</p><p>Eric started off by saying that he&#8217;s given talks on iPhone testing, but that just telling people what to do is not the same as letting them experience it for themselves,  so we did a <a href="http://codingdojo.org/cgi-bin/wiki.pl?RandoriKata" target="_blank">Randori</a>, where a pair starts working on some code, and every 3 minutes one person from the pair swaps out and chooses his replacement from the crowd.</p><p>What I liked about this was that I felt like I got to know the audience better, and actually watch people reason their way through the code or a testing/mocking issue.  (You know how sometimes you go to a user group, and it can be hard to get a chance to talk to others, or sometimes there is a &#8216;know-it-all&#8217; guy, and you just want him to shut up. Knowing that you are going to have to go up there and code is a great way to silence those types)</p><p>When it was my turn,  there was an interesting issue with one of the tests that had us all stumped for a bit, but ultimately ended up being one of those problems where you need to deconstruct everything and build it back up. (The issue was that while we were trying to set fooController.textView.text = @&#8221;foobar&#8221;, we hadn&#8217;t instantiated a textView object, or set it on the controller yet.)<br /> <span id="more-3816"></span><br /> We got into some testing, mocking strategies, and a few Xcode tips &amp; tricks, but not being all that familiar with the mocking framework, it would have been nice to just do a little intro on the api, but whenever someone was stumped the answer was shouted out pretty quickly.</p><p>It was nice to get some pizza, so a big thanks to <a href="http://www.obtiva.com/" target="_blank">Obtiva</a> &amp; <a href="http://blog.8thlight.com" target="_blank">8thlight</a> for putting this together. I wish we could do some presentations here at <a href="http://www.pathf.com/" target="_blank">Pathfinder</a>, but our space is better for a meet &amp; greet, than a presentation. (plus I don&#8217;t think as many people would come to the River North area)</p><p>I was new to a Randori, and I think this style of presentation is good, but I do have a few ideas I think I&#8217;ll include when I host one:</p><ol><li> Set out a basic agenda, introducing the approach, the codebase, relevant api, and where we&#8217;re hoping to end up</li><li> Moderate the work (and the crowd), and be ready to help out in case the pair gets stuck (which means you really have to keep an eye on what they are doing)</li><li> Make the work meaninful, and the outcome tangible. (we were able to see our posts getting pushed to twitter, which was nice)</li><li> Push the final code up to github as a branch, so they can check it out later and compare the original to what they created as a group</li></ol><p>There were a few times when I couldn&#8217;t quite hear what the pair was saying, or read the screen that well, and though it wasn&#8217;t a large group there were a few side conversations that made it harder for me to follow. I think this was most likely to happen when the pair was struggling, so a little moderation would probably keep things moving along fast enough to keep everyone engaged. I saw another post that also laid out some strategies for <a href="http://www.notesfromatooluser.com/2008/10/tdd-randori-session.html" target="_blank">how to best host a Randori session</a>.</p><p>I&#8217;m looking forward to the next chiphone meeting, and I think there was some talk of doing a group project to make a little app for next month&#8217;s <a href="http://WindyCityRails.org" target="_blank">WindyCityRails.org</a> conference.</p><p>Related Services: <a href="http://www.pathf.com/services/iphone-application-development/">iPhone Application Development</a>,<br /> <a href="http://www.pathf.com/services/technology-expertise/ruby-on-rails/">Ruby on Rails Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;linkname=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;linkname=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;linkname=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;linkname=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;linkname=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;linkname=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;linkname=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fchiphone-meeting-chicago-iphone-user-group-tdd%2F&amp;title=Chiphone%20Meeting%3A%20Chicago%20iPhone%20user%20group%20gets%20its%20TDD%20on" id="wpa2a_6">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/08/chiphone-meeting-chicago-iphone-user-group-tdd/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Javascript debugging and testing in the wild (Prototype bug when using array.flatten in IE)</title><link>http://pathfindersoftware.com/2009/08/javascript-debugging-testing-wild-prototype-bug-arrayflatten/</link> <comments>http://pathfindersoftware.com/2009/08/javascript-debugging-testing-wild-prototype-bug-arrayflatten/#comments</comments> <pubDate>Wed, 19 Aug 2009 16:49:18 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Ajax]]></category> <category><![CDATA[Rich Internet Apps]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[Javascript]]></category> <category><![CDATA[Prototype]]></category> <category><![CDATA[Testing]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=3560</guid> <description><![CDATA[I had to dig into a production issue the other day that presented itself like this: There was a piece of javascript code that iterated over some dom elements, gathered ids into 2 arrays, ran a validation check, and then flattened the arrays to add them to the url. On firefox, opera, and chrome this ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><p>I had to dig into a production issue the other day that presented itself like this:<br /> There was a piece of javascript code that iterated over some dom elements, gathered ids into 2 arrays, ran a validation check, and then flattened the arrays to add them to the url.</p><p>On firefox, opera, and chrome this was working correctly, and had been tested by the developers, but on IE 7 it isn&#8217;t working, and the problem wasn&#8217;t detected until it made it out to production. (Which raises a point about testing in IE during QA, which I&#8217;ll get to in a sec).</p><p>I started my investigation doing what I&#8217;d call &#8220;poor man&#8217;s debugging&#8221;, putting some alerts in, breaking up the code a bit to make it easier to inspect, etc. Normally I don&#8217;t do this when testing in Firefox, because I have Firebug, but in IE I always seem to start with the basics to get my bearings, then quickly move to a more pragmatic approach.</p><p>Then I started using firebug-lite, confirming that I can see the info I need, and I reverted my changes to the code so that I could verify that I hadn&#8217;t introduced any issues.<br /> <span id="more-3560"></span></p><p>After sifting through the code, checking through the prototype library to make sure that it was being used correctly, I narrowed the problem down to a single line, which I could test from the address bar of either browser (when on a page with prototype.js loaded)</p><pre style="white-space: pre !important;">
   javascript:alert([[,,,'foo'],[,'bar',,]].flatten().length == 2)
</pre><p>For me that will fail in IE 7, but pass in everything else.</p><p>I then wrote a test using jqUnit, the javascript testing library from jQuery, so that I could get into that rapid process of test => fail => fix => pass, without having to screw around with retyping or copying code, or forgetting what I&#8217;ve tried.</p><pre style="white-space: pre !important;">
	test('prototype flatten array test', function(){
	ok([[,,,'foo'],[,'bar',,]].flatten().length == 2, 'the flattened array should be 2');
	});
</pre><p>Now if I load the page with that test on it, in Safari, Firefox, Chrome, or Opera, the test passes, but if I load it in IE 7, it fails. I now have an environment where I can dig in and make changes, and quickly confirm that I didn&#8217;t break anything in the other browsers.</p><p>After a bit of investigating I conclude that the issue is within the prototype.js library itself, behaving differently between browsers for this function:</p><pre style="white-space: pre !important;">
flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(Object.isArray(value) ?
        value.flatten() : [value]);
    });
  }
</pre><p>I know that I have undefined or nil elements in my array, so I write a quick test to see how Object.isArray handles that. Turns out that it behaves the same way in all the browsers, but interestingly, it will return either True, False, or Undefined, which means that those undefined values will get added, because the flatten method above is just looking for &#8216;true&#8217;.</p><p>At this point I feel like writing a version of the method that is a bit more explicit, just to make sure that I&#8217;m on the right track. (I throw this in my test copy of prototype.js)</p><pre style="white-space: pre !important;">
//explicitly checking for true and false, because isArray returns undefined
  myflatten: function() {
    return this.inject([], function(array, value) {
    var _isArray = Object.isArray(value)
    if (_isArray == true) {
      return array.concat(value.myflatten());   //must call myflatten
    } else if (_isArray == false) {
      return array.concat([value]);
    } else {
     return array;
    }
    });
  }
</pre><p>I create another test, and see that it passes in all browsers, but I&#8217;m not really interested in going to production with a patched version of prototype, and at this point I&#8217;ve already spent enough time on this bug, so I go back to my original problem code and find another way to remove the undefined elements of the array, and get the code pushed out to prod.</p><p>After things calm down, and we&#8217;ve gotten the outstanding bugs taken care of, I wanted to take another look at the problem, because while I feel that I&#8217;ve figured out a way to stop the problem, as I still don&#8217;t understand why its happening. After some googling, I don&#8217;t really see a clear indication that other people have run into this, but I take a look at versions newer than what I&#8217;m running in prod (1.6.0.1), and I see that the isArray method was recently changed to:</p><pre style="white-space: pre !important;">
 function isArray(object) {
  return getClass(object) === "Array";
}
</pre><p>Which we can see will result in a strict true/false response, and when I reran my tests against that version, they passed, so I figure I&#8217;m done with it and we&#8217;ll just upgrade to the latest version when we can.</p><p>But something keeps nagging at me, as it seems that there&#8217;s more going on here than just the isArray method, so I dive into the code again and see that the function that is passed .inject is called more times in IE than in the other browsers, and that the code in .inject is pretty simple and just relies on .each.</p><p>I write a test to explore how .each will iterate over undefined elements in all the browsers.</p><pre style="white-space: pre !important;">
	//shows that .each will iterate over empty array elements in IE
  test('iterator test', function() {
    var hitCount = 0;
    [,,,'foo'].each(function(value){hitCount++;})
    equals(hitCount, 1, 'should be 1');
  });
</pre><p>And I see that IE iterates over the array 4 times, whereas opera, safari and chrome only iterate 1 time. Interestingly my latest copy of Firefox is behaving the same as IE, and I swear it wasn&#8217;t doing this with the previous version I had when I was originally testing this a month or so ago.</p><p>Here are the results:<br /> <a href="http://pathfindersoftware.com/wp-content/uploads/2009-08-19_11391.png"><br /> <img src="http://pathfindersoftware.com/wp-content/uploads/2009-08-19_11391.png" alt="2009-08-19_1139" title="2009-08-19_1139" width="720" height="470" class="aligncenter size-full wp-image-3562" /> </a></p><p>Conclusion:<br /> Be careful in any assumptions you make about the contents of your arrays, and their iteration, in case they contain nils, or &#8216;undefined&#8217; elements you weren&#8217;t expecting.</p><p>The other point I&#8217;d make is about the general practice of javascript debugging, and testing. If you get comfortable with firebug, and firebug-lite on IE/opera, you can save yourself a lot of time and narrow down to the issue pretty quickly. Having even a basic test suite can go a long way in ensuring that your javascript code behaves the way you expect in all of the browsers. Couple that with some selenium smoke tests, and you&#8217;ll find more bugs faster, and save a lot of wasted effort in your QA process.</p><p>Related Services: <a href="http://www.pathf.com/services/technology-expertise/ajax-and-rich-internet-applications/">Ajax Rich Internet Applications</a>, <a href="http://www.pathf.com/services">Custom Software Development</a><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;linkname=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;linkname=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;linkname=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;linkname=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;linkname=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;linkname=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;linkname=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F08%2Fjavascript-debugging-testing-wild-prototype-bug-arrayflatten%2F&amp;title=Javascript%20debugging%20and%20testing%20in%20the%20wild%20%28Prototype%20bug%20when%20using%20array.flatten%20in%20IE%29" id="wpa2a_8">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/08/javascript-debugging-testing-wild-prototype-bug-arrayflatten/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>What&#039;s the best way to programmatically edit a pdf in ruby?</title><link>http://pathfindersoftware.com/2009/07/whats-the-best-way-to-programmatically-edit-a-pdf-in-ruby/</link> <comments>http://pathfindersoftware.com/2009/07/whats-the-best-way-to-programmatically-edit-a-pdf-in-ruby/#comments</comments> <pubDate>Tue, 21 Jul 2009 21:59:10 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Ruby on Rails]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[origami]]></category> <category><![CDATA[pdf]]></category> <category><![CDATA[prawn]]></category> <category><![CDATA[rails]]></category> <category><![CDATA[ruby]]></category> <category><![CDATA[ruport]]></category> <category><![CDATA[Security]]></category> <category><![CDATA[Testing]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=3293</guid> <description><![CDATA[I&#8217;ve been doing a good deal of PDF generation in Rails, and had to go through the process of comparing all the available techniques and frameworks in order to find the right solution for my needs. Its great that there are so many tools out there, but it can be a daunting task to figure ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><p><span> </span>I&#8217;ve been doing a good deal of PDF generation in Rails, and had to go through the process of comparing all the available techniques and frameworks in order to find the right solution for my needs.</p><p><span> </span>Its great that there are so many tools out there, but it can be a daunting task to figure out which is best, which will scale, which will continue to grow and improve, and to evaluate the true &#8216;cost&#8217; of free vs. commercial.</p><p>With all this info finally digested and sorted out,  I was surprised when I got a client request to be able to add a banner to an existing pdf, and from what I can  recall, none of the libraries I know about seem able to do this.  Right now, I&#8217;m in the middle of googling the hell out of it, but haven&#8217;t found my silver-bullet answer yet.  (maybe I should ask jeeves?)</p><p><span> </span></p><p><span> </span>I&#8217;ve done various searches and have come across a few categories of PDF tools:</p><ol><li>Wrappers to existing pdf generation tools like fpdf, and iText</li><li>PDF Template tools where you build a pdf skeleton file, and bind values to it programmatically</li><li>Pure Ruby PDF Generation tools</li><li>PDF Readers and inspection tools</li></ol><p>I did find a discussion about how this <em>could </em>work on <a href="http://groups.google.com/group/pdf-writer/browse_thread/thread/f32b9693cb6d99ff/856cd9f7ceccfa8e?q=ruby+edit+existing+pdf#856cd9f7ceccfa8e">Google Groups</a> between Greg Brown creator of Prawn and Ruport, and James Healey developer of PDF::Reader, but that discussion basically ended with, &#8220;Yeah, that would be cool!&#8221;.</p><p>At this point I&#8217;m looking into the <a href="http://security-labs.org/origami/">Origami</a> library which is actually designed for pdf &#8216;security&#8217; and testing, and isn&#8217;t explicitly designed for editing pdfs in this way, but at the moment its the leading candidate in my list.</p><p><span> </span></p><p><span> </span>Have I missed something? Is there an obvious way to do this in ruby/rails that I&#8217;m completely overlooking? (I haven&#8217;t looked very deeply at tools that shell out to the bigger libraries, but I wouldn&#8217;t rule them out)</p><p>The initial requirement was to be able to add a banner/header to an existing PDF, but I can see the complexities of determining how to shift the existing content down without screwing up all the formatting, so I think even being able to insert a coverpage might be a suffcient implementation for now. (Maybe I should be searching for pdf &#8216;merging&#8217; instead of editing)</p><p>I&#8217;ll update you with my final solution in an upcoming blog post, and I&#8217;ll be covering all of the info I&#8217;ve learned on PDF Generation tools for Ruby and Rails  at this year&#8217;s WindyCityRails Conference on September 12th. Drop by <a href="http://windycityrails.org/" target="_blank">http://windycityrails.org</a> to register. (early registration ends Aug 1st)</p><p><span> </span><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;linkname=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;linkname=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;linkname=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;linkname=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;linkname=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;linkname=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;linkname=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F07%2Fwhats-the-best-way-to-programmatically-edit-a-pdf-in-ruby%2F&amp;title=What%26%23039%3Bs%20the%20best%20way%20to%20programmatically%20edit%20a%20pdf%20in%20ruby%3F" id="wpa2a_10">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/07/whats-the-best-way-to-programmatically-edit-a-pdf-in-ruby/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>ChicagoRuby meeting &#039;Test Prescriptions&#039; recap</title><link>http://pathfindersoftware.com/2009/06/chicagoruby-meeting-test-prescriptions-recap/</link> <comments>http://pathfindersoftware.com/2009/06/chicagoruby-meeting-test-prescriptions-recap/#comments</comments> <pubDate>Wed, 24 Jun 2009 18:41:45 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Software Development]]></category> <category><![CDATA[chicagoruby]]></category> <category><![CDATA[chirb windycityrails]]></category> <category><![CDATA[factory]]></category> <category><![CDATA[fixturereplacement]]></category> <category><![CDATA[fixtures]]></category> <category><![CDATA[flexmock]]></category> <category><![CDATA[mocking]]></category> <category><![CDATA[rails]]></category> <category><![CDATA[railsrx]]></category> <category><![CDATA[rspec]]></category> <category><![CDATA[ruby]]></category> <category><![CDATA[shoulda]]></category> <category><![CDATA[tdd]]></category> <category><![CDATA[test::unit]]></category> <category><![CDATA[Testing]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=2995</guid> <description><![CDATA[The ChicagoRuby users group (not to be confused with chirb.org another great Chicago Ruby user group) held their second meeting at their downtown location. While the meetings out in Elmhurst are always informative and helpful,  the downtown location may allow for a bigger crowd, and the weekday time might work better for more people. Plus, ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><div class="right"><img class="alignright size-full wp-image-2996" title="chicagorubylogo" src="http://pathfindersoftware.com/wp-content/uploads/chicagorubylogo1.gif" alt="chicagorubylogo" width="240" height="88" /></div><p>The <a href="http://www.chicagoruby.org" target="_blank">ChicagoRuby </a>users group (not to be confused with<a href="http://chirb.org/" target="_blank"> chirb.org</a> another great Chicago Ruby user group) held their second meeting at their downtown location.</p><p>While the meetings out in Elmhurst are always informative and helpful,  the downtown location may allow for a bigger crowd, and the weekday time might work better for more people. Plus, the <a href="http://www.illinoistech.org/" target="_blank">Illinois Technology Association &#8211; Tech Nexus </a> is right next to Union Station which works great for people that still have to go out to the suburbs.</p><p><span> </span> <span> </span><a href="http://www.pathf.com/blogs/author/noel-rappin/" target="_blank">Noel Rappin&#8217;s</a> talk covered some of the most <a href="http://www.pathf.com/blogs/2009/05/rails-testing-frequently-asked-questions-the-non-code-version/" target="_blank">common questions</a> he gets through the <a href="http://www.pathf.com/blogs/" target="_blank">Pathfinder Development Blog</a>, and his own site RailsPrescriptions site <a href="http://railsrx.com/" target="_blank">RailsRX.com</a> dedicated exclusivly to testing.</p><p><span> </span>There&#8217;s too much detail to cover here, but at a high-level, Noel covered:</p><ul><li>The why, how, when, and where questions that make the foundation of a good testing approach</li><li>Testing techniques for legacy projects</li><li>A good review of the different testing frameworks, what their differences are, and some discussion about each (test::unit, shoulda, rspec, cucumber)</li><li>A solid review of different <a href="http://www.pathf.com/blogs/2009/05/factory-tools-for-fixture-replacement-a-comparison/" target="_blank">factory tools</a> that go beyond standard fixtures (Factory Girl, Fixture Replacement, Machinist, and Object Daddy)</li><li>Strategies for migrating from Fixtures</li><li>Differences between the <a href="http://www.pathf.com/blogs/2009/05/comparing-ruby-mock-object-libraries/" target="_blank">mocking frameworks</a>:  Flexmock, mocha, rspec, and RR (double ruby)</li><li>Finding the right balance, and avoiding the pitfalls of &#8216;over mocking&#8217;</li><li>Cucumber testing workflow (and where cucumber doesn&#8217;t work well)</li></ul><p><span> </span> <span> </span>The audience seemed to have a wide range of experience, but all had opinions to share about what they&#8217;ve learned about testing.  After the talk everyone seemed fell into small groups to network and exchange ideas and contact info, and a group gathered around Ray and Noel as they tossed around some ideas on potential future meeting topics &#8220;Ruby IDE/Editor review&#8221;, &#8220;Rails Jumpstart&#8221;, &#8220;Coding Dojo&#8221;.</p><p>The organizers took a stab at hosting the meeting virtually over gotomeeting (not sure if it was recorded or not).</p><p>Their next meeting is scheduled for July 18th, details can be found in their <a href="http://www.meetup.com/ChicagoRuby/" target="_blank">meetup.com</a> group.</p><div class="right"><img class="alignnone size-full wp-image-2999" title="windy_city_logo" src="http://pathfindersoftware.com/wp-content/uploads/windy_city_logo1.png" alt="windy_city_logo" width="273" height="60" /></div><p>The organizers of the ChicagoRuby.com group are also the organizers of the 2nd annual <a href="http://windycityrails.org/" target="_blank">WindyCityRails </a>Conference right here in Chicago, on Sept, 12th, which Noel <a href="http://www.pathf.com/blogs/2009/06/upcoming-pathfinder-appearances/" target="_blank">will be presenting at</a>. <span> </span><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;linkname=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;linkname=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;linkname=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;linkname=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;linkname=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;linkname=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;linkname=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fchicagoruby-meeting-test-prescriptions-recap%2F&amp;title=ChicagoRuby%20meeting%20%26%23039%3BTest%20Prescriptions%26%23039%3B%20recap" id="wpa2a_12">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/06/chicagoruby-meeting-test-prescriptions-recap/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Mowing the grass, Revisited</title><link>http://pathfindersoftware.com/2009/06/mowing-the-grass-revisited/</link> <comments>http://pathfindersoftware.com/2009/06/mowing-the-grass-revisited/#comments</comments> <pubDate>Wed, 24 Jun 2009 06:17:56 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Software Development]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=2980</guid> <description><![CDATA[photo credit: great_sea A few weeks ago Alice Toth and I had a conversation about how we can better serve our clients, and while we normally delve into project efficiencies like communication, developer training, and good QA practices, this time we both concluded that we need to do a better job of helping our clients ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><div style="float:right;padding:10px"><a title="After Mowing" href="http://www.flickr.com/photos/62468090@N00/140557217/" target="_blank"><img src="http://pathfindersoftware.com/wp-content/uploads/140557217_3ebe991e53_m1.jpg" border="0" alt="After Mowing" /></a><br /> <small><a title="Attribution-ShareAlike License" href="http://creativecommons.org/licenses/by-sa/2.0/" target="_blank"><img src="http://pathfindersoftware.com/wp-content/uploads/cc12.png" border="0" alt="Creative Commons License" width="16" height="16" align="absmiddle" /></a> <a href="http://www.photodropper.com/photos/" target="_blank">photo</a> credit: <a title="great_sea" href="http://www.flickr.com/photos/62468090@N00/140557217/" target="_blank">great_sea</a></small></div><p>A few weeks ago <a href="http://www.pathf.com/blogs/author/alice-toth/" target="_blank">Alice Toth</a> and I had a conversation about how we can better serve our clients, and while we normally delve into project efficiencies like communication, developer training, and good QA practices, this time we both concluded that we need to do a better job of helping our clients reach their goals in the most efficient way possible, and sometimes that means talking them &#8216;down&#8217; from the specific implementation idea they have, and finding a faster way to get there.</p><p>I said that one of our challenges is that sometimes our clients feel they&#8217;ve hired us to just  &#8217;Mow the Grass&#8217;, not discuss the landscape architecture, so we&#8217;re not always in a place to be heard when it comes to discussing the fundamentals of a project.  Alice <a href="http://www.pathf.com/blogs/2009/05/just-mow-the-grass/" target="_blank">wrote a nice post</a> about what &#8216;Just Mow the Grass&#8217; meant to her, and the strategy she&#8217;s devised to find a nice middle ground.</p><h3>Here&#8217;s how I see it</h3><p><span id="more-2980"></span><br /> I was thinking about the times when we encounter projects that are looking for what I call &#8216;commodity software development&#8217; which is to say they feel they already have all the requirements, and everything is all figured out, and they just need a fixed-bid project to have it built. The reality though is that most of the time the idea is not fully fleshed out, and needs a good deal of work. While there might be some giant spreadsheet of features, usually the core business goals aren&#8217;t clear, and many fundamental issues have not been covered.</p><p>If the customer thinks they have hired us to just <strong>&#8216;mow the grass&#8217;</strong>, they aren&#8217;t in a place to hear any ideas about the big picture, they simply want us to &#8216;build it&#8217;, and as a consulting company we do need projects, and we want to have happy customers, so it seems we can either just build exactly what they asked for, and hope it turns out for the best, or we can help them confirm the business fundamentals a bit, and verify that the plan will work.</p><p><strong>&#8220;I didn&#8217;t hire you to question me&#8221;</strong></p><p>Its not easy to get into the fundamentals with our customers, but the overall success of our work is dependent on knowing the fundamental assumptions that led to its creation, and in my mind that means we need to explore those ideas and test them out.</p><p>The other comparison/metaphor I had been kicking around in my head goes like this:</p><p style="padding-left: 30px;">Imagine you are a building contractor. You build buildings to meet the needs of your clients, while adhering to the &#8216;best practices&#8217; of your industry. If a client comes to you and wants you to build a new &#8216;asian-fusion&#8217; restaurant in an area that you are pretty sure its not going to take off, you could suggest that another location might work better, but in reality, the customer probably isn&#8217;t interested in what a contractor has to say about the viability of a concept restaurant. If the concept doesn&#8217;t take off, the contractor still got paid, the builing is still standing and can be used for other purposes, and an outsider would not conclude that the restaurant failed because of anything related to the structure of the building itself. And while it might seem that the contractor doesn&#8217;t care if the concept restaurant succeeds or not, let&#8217;s suppose that if it had been successful it would lead to a long and successful relationship where the contractor and the business owner continue to work together on new buildings and projects.</p><p>So in this example, the &#8216;building&#8217; project has specific and measurable requirements that are independent of the big picture success of the restaurant.</p><p>Now comparing that to a software development project that is core to the business. The software product that is created is inextricably linked to the success of big picture, and the software is unlikely to stand on its own and be usable for some other business. In fact if the big picture is not successful often times the software product itself is blamed.</p><p>Some of the fundamentals of a project</p><ol><li>Is this a problem that users care about?</li><li>Is this the best way to solve that problem?</li><li>Is the business value greater than the cost to build it? (if not, how could we either lower the cost, or increase the value?)</li></ol><p>I&#8217;ve noticed this fundamental failure to align the proposed features of a product to their expected return more on iPhone projects, and other smaller budget projects. That&#8217;s not to say that its not present on larger projects, just that its more noticeable on smaller projects.</p><h2>Ok, so now what?</h2><p>Where as I was suggesting that we need to just dive into the fundamentals of the project and balance out the features relative to their expected value, and that its our job to &#8216;Fight&#8217; to make sure we&#8217;re building the right solution to the right problem, Alice&#8217;s suggestion was that we need to consistently deliver high-quality results on the tasks we&#8217;ve been charged to do, even if it is just &#8216;Mowing the grass&#8217;, in order to establish trust and credibility, and earn our place at the &#8216;big table&#8217; of advice giving.</p><p>What I don&#8217;t like about Alice&#8217;s idea is that its simple, elegant, logical, and its not mine!  (There&#8217;s nothing worse than someone taking something you said and interpreting it to be more positive and cohesive than you realized)</p><p>You may have won this round Alice, but what will you do with customers like these?</p><object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="fm_R2a8TRSgzZY&amp;hl=en&amp;fs=1_1006966601" class="flashmovie" width="545" height="413"><param name="movie" value="http://www.youtube.com/v/R2a8TRSgzZY&amp;hl=en&amp;fs=1" /><param name="play" value="true" /><param name="loop" value="false" /><param name="quality" value="best" /><param name="allowscriptaccess" value="always" /><param name="allowfullscreen" value="true" /> <!--[if !IE]>--> <object type="application/x-shockwave-flash" data="http://www.youtube.com/v/R2a8TRSgzZY&amp;hl=en&amp;fs=1" name="fm_R2a8TRSgzZY&amp;hl=en&amp;fs=1_1006966601" width="545" height="413"><param name="play" value="true" /><param name="loop" value="false" /><param name="quality" value="best" /><param name="allowscriptaccess" value="always" /><param name="allowfullscreen" value="true" /> <!--<![endif]--><p><a href="http://adobe.com/go/getflashplayer"><img src="http://pathfindersoftware.com/wp-content/uploads/get_flash_player1.gif" alt="Get Adobe Flash player" /></a></p><!--[if !IE]>--> </object> <!--<![endif]--> </object><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;linkname=Mowing%20the%20grass%2C%20Revisited" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;linkname=Mowing%20the%20grass%2C%20Revisited" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;linkname=Mowing%20the%20grass%2C%20Revisited" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;linkname=Mowing%20the%20grass%2C%20Revisited" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;linkname=Mowing%20the%20grass%2C%20Revisited" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;linkname=Mowing%20the%20grass%2C%20Revisited" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;linkname=Mowing%20the%20grass%2C%20Revisited" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2Fmowing-the-grass-revisited%2F&amp;title=Mowing%20the%20grass%2C%20Revisited" id="wpa2a_14">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/06/mowing-the-grass-revisited/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>5 things I can do with my windows mobile phone that you can&#039;t do with your iPhone</title><link>http://pathfindersoftware.com/2009/06/5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone/</link> <comments>http://pathfindersoftware.com/2009/06/5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone/#comments</comments> <pubDate>Wed, 17 Jun 2009 00:15:59 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Mobile Apps]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[Technologies and Platforms]]></category> <category><![CDATA[development]]></category> <category><![CDATA[iPhone]]></category> <category><![CDATA[tether]]></category> <category><![CDATA[Windows]]></category> <category><![CDATA[windows mobile]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=2714</guid> <description><![CDATA[After playing with my friend&#8217;s iPhone for awhile, and using the company phone for testing out our iPhone applications, I started to get really jealous of how cool it is, and how uncool my samsung windows mobile phone seems by comparison. The more I used the iPhone, the more I got upset at my windows ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><div class="right"><img class="alignright size-full wp-image-2718" title="samsung_blackjack2" src="http://pathfindersoftware.com/wp-content/uploads/samsung_blackjack2_lp1.jpg" alt="samsung_blackjack2" width="250" height="285" /></div><div>After playing with my friend&#8217;s iPhone for awhile, and using the company phone for testing out our iPhone applications, I started to get really jealous of how cool it is, and how uncool my samsung windows mobile phone seems by comparison.</div><div> The more I used the iPhone, the more I got upset at my windows phone and started demanding &#8220;Why can&#8217;t I do this on my phone?&#8221;, and the more I found that there were apps out there that I didn&#8217;t even know existed, as one of big problems with the windows platform is that its not easy to find good apps.</div><div>So here&#8217;s my take on how to make your windows phone better, and what it can do for now that the iPhone can&#8217;t do.</div><p><span id="more-2714"></span></p><div><strong>Powerful add on applications that really improve my phone:</strong></div><div><ol><li><a href="http://www.fring.com/" target="_blank"> <img class="attachment-thumbnail" src="http://pathfindersoftware.com/wp-content/uploads/fring1.png" alt="" width="150" height="74" /> Fring </a>(IM/gmail/twitter all in one tool)</li><li><a href="http://www.google.com/mobile/" target="_blank"><img class="attachment-thumbnail" src="http://pathfindersoftware.com/wp-content/uploads/latitude-48x481.gif" alt="" width="48" height="48" /> Google mobile</a> tools (maps, gmail, reader, docs)</li><li><a href="http://www.evernote.com/" target="_blank"><img class="attachment-thumbnail" src="http://pathfindersoftware.com/wp-content/uploads/evernote1.gif" alt="" width="150" height="39" /> Evernote</a> (sync pic/audio/video/text notes easily)</li><li><img class="alignnone size-full wp-image-2745" title="dashwire" src="http://pathfindersoftware.com/wp-content/uploads/dashwire1.jpg" alt="dashwire" width="230" height="87" /> <a href="http://www.dashwire.com" target="_blank"> DashWire </a>(sync all of your phone data)</li></ol></div><div><strong>What my phone can do that an iPhone can&#8217;t:</strong></div><ol><li>Tether **</li><li>Run more than one app at a time (background processing)</li><li>Support multiple browsers (IE, <a href="http://www.opera.com/mini/" target="_blank">Opera</a>, <a href="http://www.skyfire.com/" target="_blank">skyfire</a>, <a href="http://www.torchmobile.com/" target="_blank">Iris</a>)</li><li>Multimedia messaging **</li><li>Use a storage card for music, pics, etc</li></ol><p>** While there are plans for the iPhone to support tethering and multimedia messaging, AT&amp;T has not yet announced when it will be available.  (whereas I am writing this on the train right now, tethered to my phone, with just a basic data plan).  So I understand that it will be coming soon to the iPhone, but is not available yet.</p><p>To be honest I feel strongly that the first 2 are solid points, whereas the rest kind of quickly decrease in value, but I tried my best to come up with 5 things that mater, and I previously had &#8216;Record Video&#8217; at #3, but now the iPhone will support that, so I had to take it out.</p><p><strong>Tethering</strong></p><p>While I saw good reviews of the <a title="Consumer Reports review" href="http://blogs.zdnet.com/cell-phones/?p=375" target="_blank">Samsung BlackJack</a> when I was in the market for a new phone, tethering was the #1 reason I bought the phone instead of an iPhone. Being able to get on the internet with my laptop from anywhere, at anytime is a very big deal for me. I take the train to work, and often have to rush out the door at night in order to make the schedule, but its easy for me to keep working from the train, and finish up my emails, check-in/deploy code, connect to vpn, etc. and that flexibility is huge.</p><p>As a consultant it means I can provide assistance to my customers in a more flexible manner. I recently had a customer contact me with an emergency deployment issue while I was on the road, about 20mins into a 4hour drive. While still on the phone with the customer I was able to plug my usb cable in, fire up my laptop, securely connect to their network, view the logs, debug the issue, change the code/configuration, check in to github, deploy and close out the tickets over the course of 2hours, all without losing connectivity (and picking up Wendy&#8217;s on the way!).</p><p>At one point I had tried to find telnet/ssh tools for my phone that would allow me to do some work from the phone directly, but I find its just easier to tether and use all the tools of my laptop.</p><p><strong>Running Multiple applications</strong></p><p>Being able to run multiple apps at once is more important than I originally realized, as it helps me to be much more productive and connected.</p><p>Some recent use cases of mine are:</p><ol><li>Using Fring to IM a colleague about an important work email, while walking to the subway, drafting a reply to that email, opening a new tab in my browser to check the bus schedule (if its on time I&#8217;ll take that instead of the train)</li><li>Pulling up google Maps while on the road (while someone else is driving of course) to see the route to a friend&#8217;s house, using Fring to IM that friend that we&#8217;ll be there soon, and looking up events going on that weekend in the area.</li><li>Talking on the speakerphone to a customer while looking for some info in email and google docs</li></ol><p><strong>Mulitple Browsers (or browser engines)</strong></p><p>This might not be a very strong point as the browsing experience on the iPhone is pretty damn good, but I am happy to have:</p><ol><li>Multiple browsers for different uses (IE for simple mobile browsing, Iris/skyfire for a more powerful experience)</li><li>Flash video support in the browser (YouTube, Hulu), with Skyfire</li></ol><p>* I realize there are different browser options for the iPhone, but my understanding is that they all share the same platform (ie. none of them support flash in the browser)</p><p><strong>Conclusion</strong></p><p>For me the real lesson here is that I am motivated by  &#8216;tool envy&#8217;, (insert joke _here_). This is just like what I have experienced when pairing with someone using intelliJ when I was on eclipse, or they&#8217;re on a mac when I&#8217;m working on windows and its something that can drive you to look at your environment and ask &#8220;how can I make this better?&#8221; For windows mobile users I think it takes a bit of effort to find the things that make the phone better, and its a shame that Microsoft hasn&#8217;t made this process eaiser. Once the iPhone has tethering, and with lower prices coming, its much harder to justify buying anything other than an iPhone.<br /> (oh, and let me know if there is anything else I missed)</p><p>Related Services: <a href="http://www.pathf.com/services/iphone-application-development/">iPhone Application Development</a>, <a href="http://www.pathf.com/services">Custom Software Development</a><p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;linkname=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;linkname=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;linkname=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;linkname=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;linkname=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;linkname=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;linkname=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F06%2F5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone%2F&amp;title=5%20things%20I%20can%20do%20with%20my%20windows%20mobile%20phone%20that%20you%20can%26%23039%3Bt%20do%20with%20your%20iPhone" id="wpa2a_16">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/06/5-things-i-can-do-with-my-windows-mobile-phone-that-you-cant-do-with-your-iphone/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Web app security checklist (Braindump)</title><link>http://pathfindersoftware.com/2009/05/web-app-security-checklist-braindump/</link> <comments>http://pathfindersoftware.com/2009/05/web-app-security-checklist-braindump/#comments</comments> <pubDate>Thu, 14 May 2009 21:21:49 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Software Development]]></category> <category><![CDATA[braindump]]></category> <category><![CDATA[checklist]]></category> <category><![CDATA[Security]]></category> <category><![CDATA[web app]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=2443</guid> <description><![CDATA[In Yesterday&#8217;s post I said I&#8217;d put together a quick list of things to think about around web application security. This is by no means an exhaustive list, but its a set of categories and things I start to look at when doing a security assessment on an app. Web Application Security Checklist Account management ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><p>In <a href="http://www.pathf.com/blogs/2009/05/avoid-the-last-minute-security-review/" target="_blank">Yesterday&#8217;s post</a> I said I&#8217;d put together a quick list of things to think about around web application security. This is by no means an exhaustive list, but its a set of categories and things I start to look at when doing a security assessment on an app.</p><p><strong>Web Application Security Checklist</strong><br /> Account management</p><ul><li>Password management (validation, expiration, previous passwords, etc)</li><li>Account lockout (number of tries, IP auditing, etc)</li><li>Role management</li></ul><p>Data management</p><ul><li>Don&#8217;t Leak sensitive user info (SSNs, account numbers, other identity info) in URLs, cookies, sessions, logs, or printable pages.</li><li>User Auditing (who changed what, and when)</li></ul><p>Browser hacks</p><ul><li>Cross Site Scripting (XSS)</li><li>Cross Site Request Forgery (XSRF)</li></ul><p>Encrypted transport (make sure Ajax calls are secure)<br /> Encrypted storage (credit cards, ssns, etc)<br /> Server configuration (firewalls, web/app server, db)</p><p>I actually have a longer list, but its not formatted/organized very well,  so this is my first cut at sharing it with others.</p><p>What other areas do you look at when doing security checks for your web apps?</p><p>What tools do you use?<p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;linkname=Web%20app%20security%20checklist%20%28Braindump%29" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;linkname=Web%20app%20security%20checklist%20%28Braindump%29" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;linkname=Web%20app%20security%20checklist%20%28Braindump%29" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;linkname=Web%20app%20security%20checklist%20%28Braindump%29" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;linkname=Web%20app%20security%20checklist%20%28Braindump%29" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;linkname=Web%20app%20security%20checklist%20%28Braindump%29" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;linkname=Web%20app%20security%20checklist%20%28Braindump%29" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Fweb-app-security-checklist-braindump%2F&amp;title=Web%20app%20security%20checklist%20%28Braindump%29" id="wpa2a_18">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/05/web-app-security-checklist-braindump/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Avoid the last minute security review</title><link>http://pathfindersoftware.com/2009/05/avoid-the-last-minute-security-review/</link> <comments>http://pathfindersoftware.com/2009/05/avoid-the-last-minute-security-review/#comments</comments> <pubDate>Wed, 13 May 2009 10:10:34 +0000</pubDate> <dc:creator>John McCaffrey</dc:creator> <category><![CDATA[Java]]></category> <category><![CDATA[Software Development]]></category> <category><![CDATA[Technologies and Platforms]]></category> <category><![CDATA[agile]]></category> <category><![CDATA[planning]]></category> <category><![CDATA[Security]]></category> <category><![CDATA[Testing]]></category><guid isPermaLink="false">http://www.pathf.com/blogs/?p=2417</guid> <description><![CDATA[Photo Credit: Amagill under Creative Commons Attribution Security is hard Security is often an after thought, slated towards the end of a project, or after some big issue has been discovered, but the nature of security functionality, rules, roles, auditing, etc make it hard to layer in to an existing codebase effectively. Oh, and if ...]]></description> <content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;"> <a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F"><br /> <img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;source=PathSoft&amp;style=normal&amp;service=bit.ly&amp;service_api=R_8a1154b608af9e55718b231fb0025d40&amp;b=2" height="61" width="50" /><br /> </a></div><div class="right"><img class="alignright size-full wp-image-2418 right" title="Plan for security" src="http://pathfindersoftware.com/wp-content/uploads/lock_med1.jpg" alt="lock_med" width="298" height="375" /><br /> <strong>Photo Credit</strong>:<br /> <a href="http://www.flickr.com/photos/amagill/">Amagill</a> under Creative Commons Attribution</div><h3>Security is hard</h3><p><span> </span>Security is often an after thought, slated towards the end of a project, or after some big issue has been discovered, but the nature of security functionality, rules, roles, auditing, etc make it hard to layer in to an existing codebase effectively.</p><p>Oh, and if the code base isn&#8217;t sufficiently tested, you&#8217;re in for a world of hurt.</p><p><span> </span></p><p><span> </span>If you are a developer that was just asked to &#8216;do a quick security check and plug any holes&#8217;, you are now in the difficult position of managing the expectation that a two-week security review means &#8220;we&#8217;re covered&#8221;. Be realistic about what you can accomplish, setting out some short-term and long-term goals.</p><h3>Do More With Less. Start with a research &#8216;Spike&#8217;</h3><p>Instead of pushing for more time to be able to &#8216;cover it all&#8217; (even though you have no idea what &#8216;it all&#8217; is yet), it might be better to start with a shorter analysis phase, where you detail your findings, identify any trends, and include recommendations for process change.  I&#8217;ve found that even the most demanding manager is appreciative and understanding when you ask for a small amount of time in order to produce a better estimate, than to just immediately demand more time without any evidence as to why.</p><h3>Plan for success</h3><p>With your analysis and recommendations in hand,<br /> <span id="more-2417"></span> you&#8217;ll be in a better place to give an estimate on what it will take to correct the problems, and any potential side-effects, (ie. &#8220;our legacy data partners might not be able to implement their side of this new security plan on time&#8221;). Plus, the team can decide which items are the highest priority, and more importantly, you&#8217;ll have put some practices in place to prevent any new security issues from slipping in later.</p><p><span> </span>Because we are never really &#8216;finished&#8217; with security, now would be a good time to schedule the next security review, tapping another member of the team to head it up (with your guidance), so that everyone knows that security is something they should be thinking of. Instead of doing a single &#8216;big-bang&#8217; security audit headed by one person under an unrealistic deadline, you&#8217;ll rotate the responsibility through the entire team, taking smaller more managable bites, and educating everyone in the process.  Eventually your &#8216;security-review&#8217; will be a natural part of the iteration and your everyday work.</p><p>(Tomorrow I&#8217;ll post <a href="http://www.pathf.com/blogs/2009/05/web-app-security-checklist-braindump/" target="_blank">a quick checklist</a> of general areas to look into for web application security.)</p><p><span> </span></p><p>This same &#8216;analyze, prioritize, estimate, rotate&#8217; technique could be applied to any &#8216;big-bang&#8217; approach, such as:</p><ul><li>Performance tuning</li><li>Adding unit tests to legacy code</li><li>Refactoring</li><li>Releasing to Production</li></ul><p><span> </span></p><p>Your team will get into a rhythm and become more efficient as the knowledge is evenly distributed. But more importantly your customers will appreciate the stability of having smaller but more frequent changes instead of massive buggy &#8216;overhauls&#8217;. They&#8217;ll see bugs getting fixed faster, and notice that little things that have bothered them for awhile are also getting fixed. Who knows, they might even give you the feedback that leads to your next million dollar idea!<p><a class="a2a_button_linkedin" href="http://www.addtoany.com/add_to/linkedin?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;linkname=Avoid%20the%20last%20minute%20security%20review" title="LinkedIn" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/linkedin.png" width="16" height="16" alt="LinkedIn"/></a><a class="a2a_button_stumbleupon" href="http://www.addtoany.com/add_to/stumbleupon?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;linkname=Avoid%20the%20last%20minute%20security%20review" title="StumbleUpon" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/stumbleupon.png" width="16" height="16" alt="StumbleUpon"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;linkname=Avoid%20the%20last%20minute%20security%20review" title="Digg" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_dzone" href="http://www.addtoany.com/add_to/dzone?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;linkname=Avoid%20the%20last%20minute%20security%20review" title="DZone" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/dzone.png" width="16" height="16" alt="DZone"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;linkname=Avoid%20the%20last%20minute%20security%20review" title="Reddit" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_delicious" href="http://www.addtoany.com/add_to/delicious?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;linkname=Avoid%20the%20last%20minute%20security%20review" title="Delicious" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/delicious.png" width="16" height="16" alt="Delicious"/></a><a class="a2a_button_evernote" href="http://www.addtoany.com/add_to/evernote?linkurl=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;linkname=Avoid%20the%20last%20minute%20security%20review" title="Evernote" rel="nofollow" target="_blank"><img src="http://pathfindersoftware.com/wp-content/plugins/add-to-any/icons/evernote.png" width="16" height="16" alt="Evernote"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fpathfindersoftware.com%2F2009%2F05%2Favoid-the-last-minute-security-review%2F&amp;title=Avoid%20the%20last%20minute%20security%20review" id="wpa2a_20">Share/Bookmark</a></p> ]]></content:encoded> <wfw:commentRss>http://pathfindersoftware.com/2009/05/avoid-the-last-minute-security-review/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using memcached

Served from: pathfindersoftware.com @ 2012-02-09 16:57:46 -->
