<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Modifying large codebases in dynamic and static languages</title>
	<atom:link href="http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/</link>
	<description>Programming, writing, programming about writing.</description>
	<pubDate>Sat, 06 Sep 2008 02:11:20 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
		<item>
		<title>By: Steve</title>
		<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/#comment-274</link>
		<dc:creator>Steve</dc:creator>
		<pubDate>Wed, 16 Apr 2008 09:18:51 +0000</pubDate>
		<guid isPermaLink="false">http://www.stevecooper.org/?p=56#comment-274</guid>
		<description>&lt;p&gt;&lt;strong&gt;@jay&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thanks for the reply, Jay. I think I'm becoming convinced of your position. When I can next justify a decently-sized hobby project, I'll try to do it in a dynamic language with lots of tests. I'll probably do it in python.&lt;/p&gt;

&lt;p&gt;I suppose the key will be to make sure there's 100% code coverage and enough permutations to be confident of the code. How do you make sure your tests are getting enough coverage?&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p><strong>@jay</strong></p>

<p>Thanks for the reply, Jay. I think I&#8217;m becoming convinced of your position. When I can next justify a decently-sized hobby project, I&#8217;ll try to do it in a dynamic language with lots of tests. I&#8217;ll probably do it in python.</p>

<p>I suppose the key will be to make sure there&#8217;s 100% code coverage and enough permutations to be confident of the code. How do you make sure your tests are getting enough coverage?</p>]]></content:encoded>
	</item>
	<item>
		<title>By: jay</title>
		<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/#comment-273</link>
		<dc:creator>jay</dc:creator>
		<pubDate>Tue, 15 Apr 2008 22:00:00 +0000</pubDate>
		<guid isPermaLink="false">http://www.stevecooper.org/?p=56#comment-273</guid>
		<description>&lt;p&gt;i understand, but in 3 years of full time usage of ruby, it's never happened to me. Even if it happened it would be caught automatically on the staging box where I'd get an email as soon as the first exception is thrown. Also, if you do comprehensive testing it will include testing with a framework like selenium which would also catch it.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>i understand, but in 3 years of full time usage of ruby, it&#8217;s never happened to me. Even if it happened it would be caught automatically on the staging box where I&#8217;d get an email as soon as the first exception is thrown. Also, if you do comprehensive testing it will include testing with a framework like selenium which would also catch it.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Steve</title>
		<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/#comment-270</link>
		<dc:creator>Steve</dc:creator>
		<pubDate>Tue, 15 Apr 2008 14:46:47 +0000</pubDate>
		<guid isPermaLink="false">http://www.stevecooper.org/?p=56#comment-270</guid>
		<description>&lt;p&gt;&lt;strong&gt;@jay&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Thanks for taking the time to reply!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You setup a bit of a perfect storm by saying that the tests use a different logger.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was trying to get in the idea of mocks. Some objects rely on I/O; say, a logger, a database connection, or a file. When unit-testing something that calls it, you want to swap out the logger/connection/file for a mock object. Otherwise you'll hammer your event log, database, or file system when you run your tests.&lt;/p&gt;

&lt;p&gt;So let's say I'm now running a function which calls the logger; say &lt;code&gt;MyDocumentedProcedure()&lt;/code&gt;. During testing, I always set the global Logger to a new MockLogger. Well, MyDocumentedProcedure() may work absolutely fine because MockLogger is set up correctly. However, if ProductionLogger hasn't been updated, it'll fail there. Of course, ProductionLogger should have it's own set of tests, but there's no guarantee that ProductionLogger's tests aren't just out-of-step with the new log(msg, sev) function.&lt;/p&gt;

&lt;p&gt;I think it's a matter of how you want to program -- I'd like these sorts of errors found for me by the computer. It's feels natural, and I'm fluent with it. That makes me productive with this kind of system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;@steve&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;You could use a default parameter for severity&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem with this approach is that my requirements have changed. I've gone from the requirement 'All messages are logged in the same way' to, say, 'messages have a severity of Alpha, Beta, or Release, and are logged differently based on the releaseType variable'. Much of this requirement is enforced throughout the code when I change the method signature to&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;log(string message, LogSeverity severity)
&lt;/code&gt;&lt;/pre&gt;
</description>
		<content:encoded><![CDATA[<p><strong>@jay</strong></p>

<p>Thanks for taking the time to reply!</p>

<blockquote>
  <p>You setup a bit of a perfect storm by saying that the tests use a different logger.</p>
</blockquote>

<p>I was trying to get in the idea of mocks. Some objects rely on I/O; say, a logger, a database connection, or a file. When unit-testing something that calls it, you want to swap out the logger/connection/file for a mock object. Otherwise you&#8217;ll hammer your event log, database, or file system when you run your tests.</p>

<p>So let&#8217;s say I&#8217;m now running a function which calls the logger; say <code>MyDocumentedProcedure()</code>. During testing, I always set the global Logger to a new MockLogger. Well, MyDocumentedProcedure() may work absolutely fine because MockLogger is set up correctly. However, if ProductionLogger hasn&#8217;t been updated, it&#8217;ll fail there. Of course, ProductionLogger should have it&#8217;s own set of tests, but there&#8217;s no guarantee that ProductionLogger&#8217;s tests aren&#8217;t just out-of-step with the new log(msg, sev) function.</p>

<p>I think it&#8217;s a matter of how you want to program &#8212; I&#8217;d like these sorts of errors found for me by the computer. It&#8217;s feels natural, and I&#8217;m fluent with it. That makes me productive with this kind of system.</p>

<p><strong>@steve</strong></p>

<blockquote>
  <p>You could use a default parameter for severity</p>
</blockquote>

<p>The problem with this approach is that my requirements have changed. I&#8217;ve gone from the requirement &#8216;All messages are logged in the same way&#8217; to, say, &#8216;messages have a severity of Alpha, Beta, or Release, and are logged differently based on the releaseType variable&#8217;. Much of this requirement is enforced throughout the code when I change the method signature to</p>

<pre><code>log(string message, LogSeverity severity)
</code></pre>]]></content:encoded>
	</item>
	<item>
		<title>By: Steve Smith</title>
		<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/#comment-269</link>
		<dc:creator>Steve Smith</dc:creator>
		<pubDate>Tue, 15 Apr 2008 12:42:31 +0000</pubDate>
		<guid isPermaLink="false">http://www.stevecooper.org/?p=56#comment-269</guid>
		<description>&lt;p&gt;You could use a default parameter for severity&lt;/p&gt;

&lt;p&gt;def log(message, severity="low"):&lt;/p&gt;

&lt;p&gt;or do a search in files for log(&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>You could use a default parameter for severity</p>

<p>def log(message, severity=&#8221;low&#8221;):</p>

<p>or do a search in files for log(</p>]]></content:encoded>
	</item>
	<item>
		<title>By: jay</title>
		<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/#comment-263</link>
		<dc:creator>jay</dc:creator>
		<pubDate>Tue, 15 Apr 2008 04:34:44 +0000</pubDate>
		<guid isPermaLink="false">http://www.stevecooper.org/?p=56#comment-263</guid>
		<description>&lt;p&gt;I've been doing ruby full time for a few years and I have yet to run into a problem with this. First, a project wide search and replace (with confirmation on each replace) will do the trick. It's a tad slower than with fancy ide's, but it usually takes me less than 10 minutes and how often does this really happen?&lt;/p&gt;

&lt;p&gt;Second, the tests should catch the errors. You setup a bit of a perfect storm by saying that the tests use a different logger. This may get through the tests, but our staging server would catch it before it ever hit live since it emails me every time there is an error and a bad logger would error almost immediately.&lt;/p&gt;

&lt;p&gt;In the past few years I can recall 2 or 3 times that there has been a bug from dynamic code, none of it ever hit the live server, and it took maybe 1 day total time to hunt them down. Most of that time was one particular bug. How much time did we gain in productivity using ruby compared to what we lost with these bugs and the slower but infrequent refactorings? No one knows for sure, but my money is that it's been a net plus for me.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>I&#8217;ve been doing ruby full time for a few years and I have yet to run into a problem with this. First, a project wide search and replace (with confirmation on each replace) will do the trick. It&#8217;s a tad slower than with fancy ide&#8217;s, but it usually takes me less than 10 minutes and how often does this really happen?</p>

<p>Second, the tests should catch the errors. You setup a bit of a perfect storm by saying that the tests use a different logger. This may get through the tests, but our staging server would catch it before it ever hit live since it emails me every time there is an error and a bad logger would error almost immediately.</p>

<p>In the past few years I can recall 2 or 3 times that there has been a bug from dynamic code, none of it ever hit the live server, and it took maybe 1 day total time to hunt them down. Most of that time was one particular bug. How much time did we gain in productivity using ruby compared to what we lost with these bugs and the slower but infrequent refactorings? No one knows for sure, but my money is that it&#8217;s been a net plus for me.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Steve</title>
		<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/#comment-236</link>
		<dc:creator>Steve</dc:creator>
		<pubDate>Mon, 07 Apr 2008 18:39:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.stevecooper.org/?p=56#comment-236</guid>
		<description>&lt;blockquote&gt;
  &lt;p&gt;have you read “Working effectively with legacy code” by “Michael C Feathers”?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No, I've never seen it. I might have to search it out next time I'm in borders.&lt;/p&gt;

&lt;p&gt;I've seen something similar to the actionscript behaviour in Ruby -- when you call a non-existing method, it actually calls another method called missing_method, which throws an exception. However, it can be overridden, which means you can specify a kind if 'oops, sorry' behaviour to get things back on track. Either brilliance or pure evil. Or both.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<blockquote>
  <p>have you read “Working effectively with legacy code” by “Michael C Feathers”?</p>
</blockquote>

<p>No, I&#8217;ve never seen it. I might have to search it out next time I&#8217;m in borders.</p>

<p>I&#8217;ve seen something similar to the actionscript behaviour in Ruby &#8212; when you call a non-existing method, it actually calls another method called missing_method, which throws an exception. However, it can be overridden, which means you can specify a kind if &#8216;oops, sorry&#8217; behaviour to get things back on track. Either brilliance or pure evil. Or both.</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Colin Ameigh</title>
		<link>http://www.stevecooper.org/2008/04/05/modifying-large-codebases-in-dynamic-and-static-languages/#comment-234</link>
		<dc:creator>Colin Ameigh</dc:creator>
		<pubDate>Mon, 07 Apr 2008 13:45:27 +0000</pubDate>
		<guid isPermaLink="false">http://www.stevecooper.org/?p=56#comment-234</guid>
		<description>&lt;p&gt;Gah - I know what you mean.&lt;/p&gt;

&lt;p&gt;Actionscript will helpfully call the new log function with a null parameter where you've missed one out, but if you accidently type a function and called lgo(msg) instead it will just ignore the call and not raise an error message or anything!   That's what you get for using a language that you can dynamically add functions to objects on the fly.&lt;/p&gt;

&lt;p&gt;In a similar vein - I like strongly typed languages.&lt;/p&gt;

&lt;p&gt;In other news - have you read "Working effectively with legacy code" by "Michael C Feathers"?   It's all about moving towards good testing practice in existing code (rather than all the books about good testing practice that start by assuming you're writing a brand new project and don't have any dirty code to start with); and a relatively entertaining read for a dry subject.&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>Gah - I know what you mean.</p>

<p>Actionscript will helpfully call the new log function with a null parameter where you&#8217;ve missed one out, but if you accidently type a function and called lgo(msg) instead it will just ignore the call and not raise an error message or anything!   That&#8217;s what you get for using a language that you can dynamically add functions to objects on the fly.</p>

<p>In a similar vein - I like strongly typed languages.</p>

<p>In other news - have you read &#8220;Working effectively with legacy code&#8221; by &#8220;Michael C Feathers&#8221;?   It&#8217;s all about moving towards good testing practice in existing code (rather than all the books about good testing practice that start by assuming you&#8217;re writing a brand new project and don&#8217;t have any dirty code to start with); and a relatively entertaining read for a dry subject.</p>]]></content:encoded>
	</item>
</channel>
</rss>
