<?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/"
	>

<channel>
	<title>Apokalypse Software Corp. &#187; debugging</title>
	<atom:link href="http://apokalypsesoftware.com/blog/tags/debugging/feed/" rel="self" type="application/rss+xml" />
	<link>http://apokalypsesoftware.com</link>
	<description>words from the wilderness</description>
	<pubDate>Thu, 02 Apr 2009 16:48:32 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Double Vision in Xcode doesn&#8217;t Double Your Fun</title>
		<link>http://apokalypsesoftware.com/blog/2008/08/17/119/</link>
		<comments>http://apokalypsesoftware.com/blog/2008/08/17/119/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 19:39:57 +0000</pubDate>
		<dc:creator>huperniketes</dc:creator>
		
		<category><![CDATA[code]]></category>

		<category><![CDATA[debugging]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[mox]]></category>

		<category><![CDATA[process improvement]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[unit tests]]></category>

		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://apokalypsesoftware.com/?p=119</guid>
		<description><![CDATA[The Mac developer scene is loaded with a lot of helpful and supportive developers out there, sharing ideas, code and encouragement with one another. I&#8217;ve benefitted from the development community, as have the Mori and Clockwork code. I say this not only as one who&#8217;s currently putting new code into them, but seeing the comments [...]]]></description>
			<content:encoded><![CDATA[<p>The Mac developer scene is loaded with a lot of helpful and supportive developers out there, sharing ideas, code and encouragement with one another. I&#8217;ve benefitted from the development community, as have the Mori and Clockwork code. I say this not only as one who&#8217;s currently putting new code into them, but seeing the comments <a href='http://www.hogbaysoftware.com'>Jesse</a> left in the code before me!</p>
<p>So I&#8217;d like to drop an idea into your lap you might find useful for the right type of application. As there are different types of software one can develop, e.g., operating systems, utilities, paint programs and the like, they have particular usage characteristics that they encourage. Some, like <a href='http://apokalypsesoftware.com/products/mori'>digital notebooks</a> and <a href='http://apokalypsesoftware.com/products/clockwork'>desktop timers</a> for example *cough*, tend to remain in operation while the user is logged into his account. Usually, this isn&#8217;t a problem for the user. Unless, of course, the user is also someone further developing said software. Then several questions have to be answered, such as, &#8220;How do I run unit tests on builds while still running a stable version of my app?&#8221; and &#8220;How do I try out the latest build without affecting the files which are currently open in my app?&#8221;</p>
<p>On operating systems based on more primitive process management, it isn&#8217;t troublesome because each built application is fairly independent of others, and often multiple invocations of a single app can be run concurrently. It wasn&#8217;t problematic on the Mac either back on MacOS 9 and earlier, and even in the early MOX releases. But now with Launch Services, running test versions of apps you run on an all-day basis can be problematic. It&#8217;s best to give that test version some different signature so its defaults and file changes don&#8217;t corrupt your normal environment.</p>
<p>Note that this tip doesn&#8217;t prevent two versions from munging the same files; even two unrelated apps can mess up a data file if they&#8217;re updating it at the same time. What this tip does is provide an alternate identity, if you will, for test builds so MOX doesn&#8217;t try to hand it the same data set it gives the release builds of your app. You mustn&#8217;t try to open files in the test build that are currently opened by a release build.</p>
<p>Here&#8217;s how I do it:</p>
<p>1. In the Info.plist file, use the C pre-processor&#8217;s conditional compilation directive to give your app its normal metadata when a release build is made, but a special set of metadata for all other build configurations:</p>
<p><code>#if	defined(Release)<br />
	&lt;key>CFBundleIdentifier&lt;/key><br />
	&lt;string>com.apokalypsesoftware.Mori&lt;/string><br />
#else<br />
	&lt;key>CFBundleIdentifier&lt;/key><br />
	&lt;string>com.apokalypsesoftware.Mori-debug&lt;/string><br />
#endif</code></p>
<p><strong>Update:</strong> I forgot to mention that Xcode 3 and later versions now use specialized editors for the Info.plist files. To override this editor selection, bring up the file&#8217;s <strong>Info</strong> window (by selecting the file and pressing cmd-I) or the <strong>Inspector</strong> window and change the <strong>File Type</strong> setting from &#8220;text.plist.<em>whatever</em>&#8221; to &#8220;text&#8221;. Once you add the conditional to Info.plist you can change <strong>File Type</strong> back and access Info.plist in its raw form from its target&#8217;s <strong>Properties</strong> tab. That way, you can view it in either mode within Xcode. <strong><em>However</em></strong>, making any changes in Xcode&#8217;s plist editor <strong>will</strong> wipe out any conditional directive in the file, so use it only for reviewing current settings, not for actual editing!</p>
<p>2. In the <strong>Target Info</strong> window (brought up via the &#8216;Project > Edit Active Target &#8220;Mori&#8221;&#8216; menu item), select the <strong>Build</strong> tab, specify &#8220;All Configurations&#8221; for the <strong>Configuration</strong> pop-up menu, and enter &#8220;plist&#8221; in the search toolbar widget to bring up the relevant setting items.</p>
<p><img src="http://apokalypsesoftware.com/wp-content/uploads/2008/01/plist-settings.png"/></p>
<p>3. For the &#8220;Info.plist Other Preprocessor Flags&#8221; setting, enter <strong>-traditional</strong> as the value. While not needed to support the test version twin, it will help to prevent any URLs included in the Info.plist from being swallowed up by the pre-processor and possibly causing you sleepless nights because neither MOX nor the Xcode build system have the slightest idea of what the proper format for URLs are, but will behave erratically when it isn&#8217;t just so. So it&#8217;s best to make it a non-issue from the start. (No charge for that and other tips related to usage of the pre-processor you can find in <a href="http://developer.apple.com/technotes/tn2007/tn2175.html">Technical Note TN2175</a>. Incidentally, TN2175 says to use &#8220;-traditional&#8221;, but I use &#8220;-CC&#8221;. Use whatever works for the version you&#8217;re on.)</p>
<p>4. For the <strong>Info.plist Preprocessor Definitions</strong> setting, enter <em>$(CONFIGURATION)</em>. Xcode will change the display to read <strong>&lt;multiple values&gt;</strong>, but that&#8217;s okay because the value will vary according to the current build configuration. It will define a value that matches the build configuration that the pre-processor will test against in the Info.plist. (Try switching the setting in the <strong>Configuration</strong> pop-up menu of the <strong>Build</strong> tab to watch the value change to match the current setting.) This is what will direct the pre-processor to output the correct value for <strong>CFBundleIdentifier</strong>.</p>
<p>5. Check the <strong>Preprocess Info.plist File</strong> checkbox so Xcode invokes the pre-processor on the Info.plist before copying it to the application.</p>
<p>When built, you&#8217;ll be able to run the app concurrently with the release version, and without causing conflicts with data files in use by it. Of course, you won&#8217;t have your preferences set up, but that&#8217;s only a problem until you save preferences for the test version. (Remember, if you try to get around that problem by copying the release version&#8217;s defaults file that it also holds the recently opened files. Purge, close or what-have-you as appropriate!)</p>
<p>One of the extra things I attempted to do in this technique was to provide an alternate name for the private builds or test versions so they would be distinctly named for testers. We used to use naming conventions such as &#8220;Mori 1.7&#946;4&#8243; when distributing such versions back in the pre-MOX days, but including the metadata keys <strong>CFBundleExecutable</strong>, <strong>CFBundleName</strong>, and <strong>CFBundleDisplayName</strong> don&#8217;t have any noticeable effect. Any tips in this regard would be greatly welcomed.</p>
<p>I had also attempted to get the pre-processor to generate the bundle identifier with &#8220;Mori-$(CONFIGURATION)&#8221; that fit whatever build configuration was in effect automatically, which would&#8217;ve avoided the use of the <strong>#if defined</strong> directive. Unfortunately, because the macro expansion would generate Mori-Release that method proved ineffective.</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/oneillicon.png'/ style="float:left"/> A corresponding idea is to use an alternate icon (via the <strong>CFBundleIconFile</strong> specifier) to represent the test version of your app. It helps you and your testers realize when odd behavior is due to running the wrong build just by looking at the dock or application-switcher. It&#8217;s also fun to double-click a document only to realize the test app is opening vital data meant only for the stable version. Hilarity is sure to ensue. But I&#8217;m a professional, don&#8217;t you kids try this at home!</p>
<p>If you don&#8217;t have the construction guy handy, you can resort to the technique I used before I discovered Info.plist processing: MOX&#8217;s own stamping of missing dock files makes for a handy visual guide to your test app. To try it yourself, add the debug version from within your <strong>build/Debug</strong> folder to your dock items. That&#8217;s right, the debug version (or whatever you use for test builds). Now delete it and empty the trash. (You will be building new ones, won&#8217;t you?) Now click on the app icon you just added to the dock. It adds a big fat &#8216;?&#8217; to your lovely icon, doesn&#8217;t it? (At least it should if you deleted the correct icon.) Now rebuild your app and run it <strong>from within Xcode</strong>.</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/docked-alternate.png' /></p>
<p>Now bring up the application switcher (cmd-tab). What do you see? A big fat ol&#8217; &#8216;?&#8217; emblazoned on the debug version of your app! Oh, you don&#8217;t? You see the normal icon? Yeah, you&#8217;re on Leopard, aren&#8217;t you? This trick doesn&#8217;t work as well on Leopard because MOX validates the file state more often than Tiger did. Such as, starting the test build from the Dock instead of only within Xcode. On Leopard, clicking on the dock icon when there&#8217;s a built debug version of your app in the debug folder will restore its unstamped icon. But anytime the question mark goes away, just delete the debug version, empty the trash, and click on the dock icon again.</p>
<p>Have fun, and keep &#8216;em flying!</p>
]]></content:encoded>
			<wfw:commentRss>http://apokalypsesoftware.com/blog/2008/08/17/119/feed/</wfw:commentRss>
		</item>
		<item>
		<title>An Urgent Mori 1.6.10 Release To Correct Bugs, and Workaround Spotlight Flaws</title>
		<link>http://apokalypsesoftware.com/blog/2008/02/27/110/</link>
		<comments>http://apokalypsesoftware.com/blog/2008/02/27/110/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 20:54:33 +0000</pubDate>
		<dc:creator>huperniketes</dc:creator>
		
		<category><![CDATA[apple]]></category>

		<category><![CDATA[bugs]]></category>

		<category><![CDATA[debugging]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[leopard]]></category>

		<category><![CDATA[localization]]></category>

		<category><![CDATA[mori]]></category>

		<category><![CDATA[mox]]></category>

		<category><![CDATA[rant]]></category>

		<category><![CDATA[tiger]]></category>

		<category><![CDATA[unit tests]]></category>

		<guid isPermaLink="false">http://apokalypsesoftware.com/blog/2008/02/27/110/</guid>
		<description><![CDATA[While making the changes to Mori&#8217;s code for 1.7, I encountered some oddities in test results, and it turned out there was a bug which I had introduced in an earlier release. While it doesn&#8217;t appear to endanger data in Mori notebooks, it might not return all the results you expect in a search, or [...]]]></description>
			<content:encoded><![CDATA[<p>While making the changes to Mori&#8217;s code for 1.7, I encountered some oddities in test results, and it turned out there was a bug which I had introduced in an earlier release. While it doesn&#8217;t appear to endanger data in Mori notebooks, it might not return all the results you expect in a search, or in entry summaries.</p>
<p>In addition, it has what I hope are a couple of performance improvements, continued improvements to Italian localization, and a work-around for Leopard&#8217;s insistence to treat non-Apple Spotlight metadata files as third-class citizens.</p>
<p>Normally when Spotlight discovers a file has been created or changed, it will ask the responsible program to figure out what&#8217;s inside, and feed it back to Spotlight. But one of the drawbacks to Spotlight&#8217;s design is it lacks the ability to define containers, or documents which contain logically distinct elements such as the chapters of a book, pictures in a photo album, or entries from a Mori notebook; and which can nest other containers as well. Treating a document as a single entity, Spotlight will open a document at the beginning (or maybe the place where the cursor was the last time it was open), even if what you&#8217;re looking for is somewhere near the end.</p>
<p>Because it doesn&#8217;t understand that a file can have distinct elements, the development teams for other Apple software (e.g., iPhoto, Safari, Stickies, etc.) came up with a scheme to trick Spotlight by creating new files with the data for those elements. So that&#8217;s how Jesse coded Mori&#8217;s behavior: duplicate the data for that logically distinct element in its own file. A separate copy of each element&#8217;s data in its own file. One extra file per element. That means the space taken up by your data is easily half again more than if Apple just added a container definition for Spotlight metadata (once for the notebook, another for the entry metadata file, and the third copy in Spotlight&#8217;s database).</p>
<p>But that isn&#8217;t all. While we&#8217;d like to keep all those extra files inside a notebook bundle (a directory which Finder treats as a file), because Spotlight treats a document as a single element it won&#8217;t look for those files inside the bundle. So Mori creates those files in the metadata cache folder (in your Library/Caches/Metadata folder), along with the metadata files from some of Apple&#8217;s programs. If you open the metadata folder and look at these files, you&#8217;ll see they have numbers to help Mori figure out which entry contains that data. But when you do a search using the Spotlight menu, and when you select menu item &#8216;Show All&#8217; and the results are displayed in the Finder, you won&#8217;t see the numbers; you&#8217;ll see the titles for the entries they represent.</p>
<p>Leopard however, isn&#8217;t so democratic; which is why users where complaining about the entries when Leopard was released. First off, it ignores any non-Apple metadata files in the cache folder <em>unless</em> you set your Spotlight preferences to use those files. Secondly, it will ignore the title info embedded in the entry metadata file and just display the file&#8217;s actual title, meaning the number. How&#8217;s that for Apple <strong>undermining the work of third-party developers</strong>?</p>
<p>So the workaround I came up with is to add the entry&#8217;s title (or Untitled, if it has none) at the <em>beginning</em> of the filename, so you at least have an idea which entry matches your search terms.</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/02/refilename.png' alt='Spotlight Filename Workaround' /> (Thanks for wasting about a whole month total of my development time on that alone, Apple. I feel the love.)</p>
<p>I am, of course, more than happy to eat crow should I be proven to be completely mistaken or speaking from out-dated information. It&#8217;s easily worth it in order to improve the user experience.</p>
<p>Regardless of the rationale for the design decisions, <a href='http://apokalypsesoftware.com/products/files/releases/Mori-1.6.10.zip'>enjoy</a>, and thank you for being part of the community and continuing to support Mori!</p>
]]></content:encoded>
			<wfw:commentRss>http://apokalypsesoftware.com/blog/2008/02/27/110/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Solving a New Event Bug Present in iCal When Scripting</title>
		<link>http://apokalypsesoftware.com/blog/2008/01/25/100/</link>
		<comments>http://apokalypsesoftware.com/blog/2008/01/25/100/#comments</comments>
		<pubDate>Fri, 25 Jan 2008 16:46:44 +0000</pubDate>
		<dc:creator>huperniketes</dc:creator>
		
		<category><![CDATA[AppleScript]]></category>

		<category><![CDATA[bugs]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[debugging]]></category>

		<category><![CDATA[iCal]]></category>

		<category><![CDATA[mgtd]]></category>

		<category><![CDATA[mori]]></category>

		<category><![CDATA[mox]]></category>

		<category><![CDATA[process failure]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[tiger]]></category>

		<guid isPermaLink="false">http://apokalypsesoftware.com/blog/2008/01/25/100/</guid>
		<description><![CDATA[While trying to solve a user&#8217;s problem with an mGTD script, I came across a subtle issue that demonstrates some issues that arise when violating a programming philosophy, tackling bugs in other people&#8217;s code, and general uncertainty whenever coding in AppleScript.
Working with AppleScript is generally considered iffy, because a lot seems ambiguous and so much [...]]]></description>
			<content:encoded><![CDATA[<p>While trying to solve a user&#8217;s <a href='http://apokalypsesoftware.com/products/node/2597'>problem with an mGTD script</a>, I came across a subtle issue that demonstrates some issues that arise when violating a programming philosophy, tackling bugs in other people&#8217;s code, and general uncertainty whenever coding in AppleScript.</p>
<p>Working with AppleScript is generally considered iffy, because a lot seems ambiguous and so much is dependent on how the dialect is interpreted and how scriptable apps handle some of the application events which scripting is dependent on. I&#8217;ve written scripts before, some I&#8217;m pretty awed by (that it works, actually, but also what it does), but I&#8217;m still hesitant to tackle some scripting issues. In addition, being a GTD greenhorn, and an mGTD noob made trying to respond to this issue authoritatively very questionable.</p>
<p>Thankfully, BMEGuy, mGTD&#8217;s author and all-around community nice guy, tackled the question with a quick solution. But the updated script was still problematic, and so I felt I really needed to participate in coming up with a solution.</p>
<p>Again, being an mGTD noob and all, it took me at least half an hour to figure out how the plugin worked, and the script on top of that. Then, after I was able to get the script to run, it worked for me. Hmm.</p>
<p>But that&#8217;s because I was testing with an entry with a date due of today. Once I switched it to later in the week, the entry was still showing up for today. <em>Isn&#8217;t that odd?</em> It seemed I had inadvertently left in the date line from the original script. When I removed it, I witnessed the same problem.</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/icalbugweek.png' alt='Artifacts of the shy scripted event' align='left' /></p>
<p>It turns out there&#8217;s a bug in MOX 10.4.11&#8217;s iCal 2.0.5 (I&#8217;m guessing it&#8217;s present in earlier versions as well) where it doesn&#8217;t properly update the calendar display for new events made by the script. You won&#8217;t see it in the monthly view. However, you might notice a little oddness in the weekly view.</p>
<p>You can see the event if you add &#8217;show theEvent&#8217; after the script makes a new display alarm for the event (between the 2nd and 3rd &#8216;end tell&#8217; up from the bottom). This will display it&#8217;s properties in the info drawer, but you won&#8217;t see the event anywhere on the calendar (in either week or month view) until iCal is restarted.</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/icalbugweekshow.png' alt='Although the event doesn't show up in the calendar, its properties are displayed in the info drawer' /></p>
<p>Running the script in monthly view doesn&#8217;t show any artifact in the calendar, but the data is shown in the info drawer.</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/icalbugmonthshow.png' alt='icalbugmonthshow.png' /></p>
<p>You could also run the script in the weekly view and then switch to the monthly view, in which case you get this: </p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/icalbugmonthswitched.png' alt='icalbugmonthswitched.png' align='left' /></p>
<p>So now that the question of the event&#8217;s presence in the calendar was settled in my mind, I had to figure out why my faulty script displayed the event, but not the proper one; and how to coax iCal to display it.</p>
<p>Being unfamiliar with mGTD still, I tried to figure out the difference between the <var>attribute name &#8220;dateDue&#8221;</var> and <var>due date</var>. <var>due date</var> is one of the standard properties for entries in a Mori document. <var>attribute name &#8220;dateDue&#8221;</var> is a user column added in the example mGTD notebook. You can view them all the user columns by selecting the menu item <q>Edit > Edit Notebook Columnsâ€¦</q></p>
<p>Okay, good so far, but why would one cause iCal to display properly and not the other? After moving the <var>due date</var> line about for a while, I checked <em>Script Editor</em>&#8217;s <cite>Event Log</cite>, and saw</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/icalbugmissingvalue.png' alt='icalbugmissingvalue.png'/></p>
<p>The event reply for the <var>due date</var> had a <q>missing value</q>! Mori wasn&#8217;t returning a value for the <var>due date</var> property because it wasn&#8217;t set (and wouldn&#8217;t be in the example notebook). Now I had to find a way to use one of those missing values to make <var>theEvent</var> visible without setting it to the wrong date. And the problem with that is most of the properties used in Mori&#8217;s entries aren&#8217;t appropriate for an iCal event.</p>
<p>I eventually thought about re-ordering the messages to iCal instead of being so fixated on a change in the messages to Mori or playing with the properties being set in creating the event. What I came up with was a plan to use the messed up <q>missing value</q> date as before to make the event visible first, and <em>then</em> set the date correctly. The code turned out like this:</p>
<pre>
tell application "Mori"
	tell current entry
		set theDate to (get attribute name "dateDue")
		set faultyDate to due date
		set theName to name
		set theNote to note
	end tell
end tell
tell application "iCal"
	tell calendar "Scramble" -- the user should specify the name of the target calendar here
		set theEvent to make new event at end with properties {description:theNote, summary:theName, start date:faultyDate, allday event:true}
		tell theEvent
			make new display alarm at end with properties {trigger date:theDate}
		end tell
		-- show theEvent
		set theEvent's start date to theDate
	end tell
end tell
</pre>
<p>And to my surprise, it worked! So as I began gathering the materials together for my reply to the issue, I noticed something in the event&#8217;s info drawer that had escaped my attention before:</p>
<p><img src='http://apokalypsesoftware.com/wp-content/uploads/2008/01/icalbughilite.png' alt='The previous script set up appointments for H. G. Wells.' align='left' /></p>
<p>iCal, that&#8217;s just crazy talk! But at least it would explain why it would display traces of an event, if anything at all; and why it wasn&#8217;t noticeable earlier: iCal would correct the event data when reading it in when it started (&#8221;iCal database, that&#8217;s just crazy talk!&#8221;). But somebody forgot to add a sanity check when creating a new event from the properties passed to it by our script. (This is an example of why the <a href='http://en.wikipedia.org/wiki/Once_and_only_once'>Once and Only Once</a> principle should be heeded. If there&#8217;s only one place where events are synthesized from pre-recorded values, whether those values are from a stored file, a script or the UI, then all those code paths will benefit from any sanity checks added to event creation.)</p>
<p>Knowing this, here&#8217;s another means of working around this bug, by sending iCal info that won&#8217;t confuse it:</p>
<pre>tell application "Mori"
	tell current entry
		set theDate to (get attribute name "dateDue")
		-- set faultyDate to due date
		set theName to name
		set theNote to note
	end tell
end tell
tell application "iCal"
	tell calendar "Scramble" -- the user should specify the name of the target calendar here
		set theEvent to make new event at end with properties {description:theNote, summary:theName, start date:theDate, end date:(theDate + 1), allday event:true}
		tell theEvent
			make new display alarm at end with properties {trigger date:theDate}
		end tell
		-- show theEvent
		-- set theEvent's start date to theDate
	end tell
end tell
</pre>
<p>Thinking about these two solutions it&#8217;s clear that picking the latter one, with well-formed properties, is the safest choice to make. <strong>Here&#8217;s additional proof:</strong> the first solution, the one which plays with the start date to make the event appear, will indeed make the event appear. But if there&#8217;s less than 24 hours until the event begins, <em>it will appear on the wrong date</em> and still require iCal to be restarted to appear in the proper location!</p>
<p>It just goes to show you, while you might be able to get away with just the barest minimum, and someone else might normally clean up after you, it&#8217;s best if you did the job correctly from the start in case your safety net disappears from under you.</p>
]]></content:encoded>
			<wfw:commentRss>http://apokalypsesoftware.com/blog/2008/01/25/100/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Day&#8217;s Not Done Yet</title>
		<link>http://apokalypsesoftware.com/blog/2007/12/25/92/</link>
		<comments>http://apokalypsesoftware.com/blog/2007/12/25/92/#comments</comments>
		<pubDate>Wed, 26 Dec 2007 03:51:44 +0000</pubDate>
		<dc:creator>huperniketes</dc:creator>
		
		<category><![CDATA[debugging]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[mori]]></category>

		<category><![CDATA[process failure]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[unit tests]]></category>

		<guid isPermaLink="false">http://apokalypsesoftware.com/blog/2007/12/25/92/</guid>
		<description><![CDATA[it&#8217;s been excessively frustrating and tiring. To cap off the season I was hoping to release the overdue 1.6.8 today, but there are still difficulties in getting the new defaults system working correctly.
The debugger is failing in the middle of an initializer method (self becomes 0&#215;1, and the argument becomes invalid), which typically indicates an [...]]]></description>
			<content:encoded><![CDATA[<p>it&#8217;s been excessively frustrating and tiring. To cap off the season I was hoping to release the overdue 1.6.8 today, but there are still difficulties in getting the new defaults system working correctly.</p>
<p>The debugger is failing in the middle of an initializer method (self becomes 0&#215;1, and the argument becomes invalid), which typically indicates an invalid pointer, but I&#8217;m just using -[NSCharacterScanner scanInt:], which shouldn&#8217;t be so problematic. (But it is, after all, Cocoa.) And it turns out that isn&#8217;t the correct tactic to use anyway as I want to extract info from the internal version number (MMmmb.bs.rr), not the public (MM.mm.bb[s[rr]]), and Cocoa doesn&#8217;t have an API for handling fixed-length records. (Possibly the <a href='http://supportline.microfocus.com/documentation/books/ocds42/lrpdf4.htm#s018'>only functionality</a> from COBOL I actually miss! I mean, there are BCD libraries for C, right?)</p>
<p>So I&#8217;ve spent much of the day tussling through docs and links for various RegEx frameworks for Cocoa, and trying to add <a href='http://regexkit.sourceforge.net/'>RegexKit</a> to the Blocks plugin framework; first 0.5beta and then 0.4beta via compilation. Now I&#8217;m attempting to use the prebuilt binary, which is problematic because frameworks are normally used by applications, <a href='http://lapcatsoftware.com/blog/2007/08/11/embedding-frameworks-in-loadable-bundles/'>not plugins</a>, so it doesn&#8217;t exactly fit right (or run). But as the clock&#8217;s been ticking, it looks like it&#8217;s time to punt and attempt another tactic by hard-coding a parser for the internal version scheme or using defaults for the optional fields in the public version scheme.</p>
<p>This is just to fix the bugs in the version class I added in an earlier version, which I have to get out of the way to continue fleshing out the revamped defaults system I created with unit tests and component code in order to release! Argh!</p>
<p>It hasn&#8217;t been all sweat and tears, though. I went through a period of idea generation (both software and marketing/entrepreneurism) early during the process and also, last night as I was organizing several years of accumulated papers, bills and what-not, found several new UI ideas I had come up with (and forgotten) and the missing FreeHand install CDs.</p>
<p>Now to get these final PITA problems licked so I can continue to move Mori forward!</p>
]]></content:encoded>
			<wfw:commentRss>http://apokalypsesoftware.com/blog/2007/12/25/92/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mori: v1.6.7 Post-Mortem and Upcoming Changes</title>
		<link>http://apokalypsesoftware.com/blog/2007/11/27/79/</link>
		<comments>http://apokalypsesoftware.com/blog/2007/11/27/79/#comments</comments>
		<pubDate>Tue, 27 Nov 2007 22:34:19 +0000</pubDate>
		<dc:creator>huperniketes</dc:creator>
		
		<category><![CDATA[agile]]></category>

		<category><![CDATA[apple]]></category>

		<category><![CDATA[cvs]]></category>

		<category><![CDATA[debugging]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[gtd]]></category>

		<category><![CDATA[hogbaysoftware]]></category>

		<category><![CDATA[leopard]]></category>

		<category><![CDATA[localization]]></category>

		<category><![CDATA[mgtd]]></category>

		<category><![CDATA[mori]]></category>

		<category><![CDATA[mox]]></category>

		<category><![CDATA[process improvement]]></category>

		<category><![CDATA[refactoring]]></category>

		<category><![CDATA[scm]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[subversion]]></category>

		<category><![CDATA[taskpaper]]></category>

		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://apokalypsesoftware.com/blog/2007/11/27/79/</guid>
		<description><![CDATA[Well, it looks like the latest toolbar fix has finally stuck. There were actually a few, very subtle interrelated items, and some procedural issues that cascaded into others. Code was shifted around hither and yon, resulting in elimination of two of a main class&#8217; instance variables and simplification of logic in several methods.
Speaking of which, [...]]]></description>
			<content:encoded><![CDATA[<p>Well, it looks like the latest toolbar fix has finally stuck. There were actually a few, very subtle interrelated items, and some procedural issues that cascaded into others. Code was <a href='http://en.wikipedia.org/wiki/Refactoring'>shifted around</a> hither and yon, resulting in elimination of two of a main class&#8217; instance variables and simplification of logic in several methods.</p>
<p>Speaking of which, I&#8217;d really love to try out Xcode3&#8217;s new refactoring tools, but that would mean
<ol>
<li>spending more time in Leopard, which freezes on me,</li>
<li>and spending more time in Xcode3, whose text editing I already loathe.</li>
</ol>
<p>I will need to investigate how well refactoring works in TextMate (which I already own and use from time to time when bumping against some other Xcode2 limitation.)</p>
<p>The <a href='http://www.igda.org/articles/erobinson_crunch.php'>pressure cooker development level</a> of the past couple of weeks really put the development process here through the wringer. Some things held up. Some things fell apart. So more &#8216;behind the scenes&#8217; development is going to take place here to minimize the interference caused by the mismatch between what needs to be done and what the tools require me to do next.</p>
<ol>Some observations of the release&#8217;s development:</p>
<li><strong>The primary, agile-based, processes were abandoned in the panic over the continued toolbar problems and Leopard incompatibilities.</strong><br />
There was no established process for handling emergencies, so the chaotic edit-compile-test behavior resurfaced. This is not to be repeated.</p>
<p><strong>Corrective Measures:</strong> A plan of action for dealing with emergencies must be established. Exercises and drills prepared and performed so the proper outcome occurs next time.
</p>
</li>
<li><strong>Users seemed to be unaware, or unconvinced, of my plans for Leopard.</strong><br />
Although I had made statements regarding the planned support for Leopard, it was only in response to questioning by users. I had failed to provide information ahead of time and prominently.</p>
<p><strong>Corrective Measures:</strong> While users refer to the forum when there are questions or they have some issue to resolve, they refer to the blog constantly. It&#8217;s best to have already disclosed plans so users have time to assimilate needed info and prepare accordingly. Blog. Blog. Blog. Forum posting: link to blog. Then blog.</p>
</li>
<li><strong>Unit testing got skipped.</strong><br />
It was unavoidable given the current process because tests didn&#8217;t cover the critical issue being developed: the user interface (i.e., toolbar items and empty windows).</p>
<p><strong>Corrective Measures:</strong> Mock objects are inadequate to sufficiently test the UI. For all my blustering that the UI <em>is testable</em>, it&#8217;s clearly time I seek or develop the necessary tools and put them to use.
</p>
</li>
<li><strong><a href='http://subversion.tigris.org'>Subversion</a> is a win, but it&#8217;s an ugly win.</strong><br />
Being able to restore files, or the project, of a particular beta or release build, or of a particular date and time, is great. Being able to make wholesale changes to the project, then abandoning them, or keeping them along a separate branch to continue experiments at a later date without juggling project directories here and there, is great. Being able to merge or contrast multiple working project directories from separate environments (Tiger, Leopard, laptop, and the v1.6.3 release) quickly and easily, is great.</p>
<p>Nibs saved as a smattering of files in the repository: not so great. Confusing subversion with its own metadata when copying/adding directories: not so great. Performing an add/delete when moving or copying directories and files instead of adding &#8220;move&#8221; or &#8220;copy&#8221; semantics to the system: not so great. Poor integration mechanism for multiple offline revisions: not so great.</p>
<p><a href='http://en.wikipedia.org/wiki/Source_code_management'>SCM</a> is great. I&#8217;ve used <a href='http://www.nongnu.org/cvs/'>CVS</a> for years. I&#8217;ve even set up another project or two using Subversion before I <a href='http://apokalypsesoftware.com/news/apokalypse-software-corp-acquires-mori-clockwork-from-hog-bay-software/'>bought Mori and Clockwork</a> from <a href='http://hogbaysoftware.com'>Jesse</a>. But I don&#8217;t see where it&#8217;s an obviously better package than CVS, but perhaps that&#8217;s because I&#8217;ve learned to work around CVS&#8217; shortcomings. (Reviewing the feature list at <a href='http://subversion.tigris.org/'>http://subversion.tigris.org</a>, the only practical feature I see that means anything to someone actually <em>using</em> Subversion is command-level manipulation of directories, although the handling of renames is poor. Hrmm. And svn+ssh access to the repository, with <a href='http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeUserGuide/Contents/Resources/en.lproj/12_UsingSubversion/chapter_951_section_3.html'>Xcode integration</a> even!)</p>
</p>
<p><strong>Corrective Measures:</strong> For the time being, the messiness of the metadata in copies and moves will have to remain unsettled. As long as the structure ends up correct, and it doesn&#8217;t take long to get it to that state, it remains tolerable in the face of bigger issues. A procedure must be established to handle the circumstance where developers are offline and must &#8220;commit&#8221; in some manner which is transferrable to the repository when they are back online.
</p>
</li>
<li><strong>Debugging is severely inadequate for professional-grade development.</strong><br />
Can you tell Apple&#8217;s team has a severe case of <a href=http://freemasonry.bcy.ca/fiction/other/our_gang.html'>he-man, mouse-haters club</a> insecurities? (Either that, or they&#8217;re <a href='http://apokalypsesoftware.com/blog/2007/04/13/33/'>operating in crunch mode</a> so much, they don&#8217;t have time to develop the appropriate tools. Nah!) The debugging facilities they provide for developers operate primarily through the use of environment variables, console output and functions and output which require gdb to access.</p>
<p>ZeroLink didn&#8217;t work well and was abandoned; Fix and Continue is still problematic; and the vaunted debug libraries (to help you catch errors in the parameters passed to the AppKit and Foundation libraries) hasn&#8217;t worked right since 10.4.3.</p>
<p>My own debugging facilities are rudimentary and lacking in depth. More of the failures in the field should be communicated back to me (remember Safari&#8217;s &#8216;bug&#8217; button?). The crash reporting mechanism should work when the crash occurs, not the next time Mori runs. Also, exceptions are logged to the console, but otherwise go unnoticed by Mori and the user.</p>
<p><strong>Corrective Measures:</strong> Extend the runtime monitoring and browsing tools. Rewrite the crash reporting mechanism to activate when the application terminates. Add an exception handler which sends reports back. Develop proper high-level debugging tools for Objective-C, the UI, CoreData and Bindings. Coding takes place at a higher level. Debugging should be at least at that same level. <em>-fobjc-gc</em> exists for a reason. Take advantage of it!
</p>
</li>
<li><strong>The build process is inconsistent, confused and unstable.</strong><br />
The various plugins&#8217; build settings aren&#8217;t consistent. Extraneous resources (images, sounds, etc.) are stored in the nibs. At times the build directory must be purged for a functioning executable to be built.</p>
<p><strong>Corrective Measures:</strong> A Build Settings Table has already been prepared and Mori and its plugins have had their settings documented. The settings for the Blocks plugins has yet to be documented. The effect of some settings has to be determined, which can then be propagated to the targets as appropriate. The project file should be purged of duplicated actions, unnecessary references, etc.
</p>
</li>
<li><strong>Debugging Mori when it&#8217;s used for normal work results in too much human activity thrashing.</strong><br />
Because the debug and test versions use the same preferences/file settings, the release version used for normal work had to be exited to avert data corruption in the notebooks.</p>
<p><strong>Corrective Measures:</strong> This issue was resolved with the Oneill branch. However, that uses a separate target to achieve its distinction. Some means of specifying a special bundle id for the debug and test builds must be developed to accomplish a similar effect, perhaps through preprocessing the Info.plist.</p>
</li>
<li><strong>Checklists are great</strong><br />
Being able to state that processes are being followed, builds are complete, and updates were released correctly, is great.</p>
<p><strong>Corrective Measures:</strong> Checklists are great, but scripted procedures are better. Automate as much of every process as possible.
</p>
</li>
<li><strong>To-Do lists, Getting Things Done (GTD), or whatever Time Management activity that is put into practice definitely helps.</strong><br />
I&#8217;ve got the <a href='http://www.davidco.com/store/catalog/Getting-Things-Done-Abridged-CD-p-16179.php'>audio book</a>. Mori&#8217;s got the <a href='http://apokalypsesoftware.com/products/node/2243'>plugin</a>. I&#8217;ve got <a href='http://hogbaysoftware.com/products/taskpaper'>Taskpaper</a>, too. I&#8217;ve got a Handspring <a href='http://www.palm.com/us/support/visor/visoredge/'>Visor Edge</a> and its Palm Desktop software. Something, anything, that helps track tasks that need to be done so nothing falls between the cracks is a plus. They are effective at keeping things moving forward, but I&#8217;m not efficient at it and a lot of discipline and effort must be used to keep moving things forward.<br />
<strong>Corrective Measure:</strong> I used TaskPaper to handle the tracking during this hectic period. I&#8217;ve got a blog entry in preparation, but basically, I found it a great way to get into the GTD system due to its simple interface. I must continue developing my understanding of this system to manage my activities, and see about getting the various software/devices integrated better.</li>
</ol>
<p />
<p />
<h2>Next Batch of Changes</h2>
<p>I&#8217;ve already begun work on v1.6.8: Improved checking and repair functionality for notebooks. <em>Correct</em> Italian localization, thanks to Mario Pettenghi. The code for the Blocks framework will be tweaked so it compiles without triggering warnings (e.g., unused parameters, missing prototype, etc.). Additional unit testing for the UI, and refactoring of UI code.</p>
<p>These improvements to the code will set up the continuation of progress for v1.7, which should then be ready during the holidays. At least that&#8217;s the current goal.</p>
]]></content:encoded>
			<wfw:commentRss>http://apokalypsesoftware.com/blog/2007/11/27/79/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
