<?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>&#34;Hello World&#34; - The SlickEdit Developer Blog &#187; Productivity</title>
	<atom:link href="http://blog.slickedit.com/category/productivity/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.slickedit.com</link>
	<description>&#34;Hello World&#34; - The SlickEdit Developer Blog</description>
	<lastBuildDate>Tue, 08 Jun 2010 18:45:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Key Binding, Command, Menu: The Golden Triangle</title>
		<link>http://blog.slickedit.com/2010/05/key-binding-command-menu-the-golden-triangle/</link>
		<comments>http://blog.slickedit.com/2010/05/key-binding-command-menu-the-golden-triangle/#comments</comments>
		<pubDate>Wed, 19 May 2010 19:45:43 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Code Editors]]></category>
		<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=529</guid>
		<description><![CDATA[To borrow a phrase from Mr. Jinks[i], “I hate meeses to pieces”. Before you call the SPCA, let me be clear that I’m talking about computer mice and not Mus musculus, the common household mouse. Further, I should narrow my context to that of programming because in many other areas of computing the mouse is [...]]]></description>
			<content:encoded><![CDATA[<p>To borrow a phrase from Mr. Jinks[i], “I hate meeses to pieces”. Before you call the SPCA, let me be clear that I’m talking about computer mice and not <em>Mus musculus</em>, the common household mouse. Further, I should narrow my context to that of programming because in many other areas of computing the mouse is indispensable.</p>
<p>In programming, however, the mouse can be one of the greatest productivity sinkholes. Time is wasted each time you lift your hand from the keyboard to grab the mouse, and more time is wasted when you move your hand back to home row in preparation for more typing.</p>
<p>So what’s the solution? Keep your hands on the keyboard! To do this use the SlickEdit<sup>®</sup> command line and bind commonly used commands to keys.</p>
<p><strong></p>
<p>Launching Operations<br />
</strong>SlickEdit provides three ways to launch operations: key bindings, commands, and menus. OK, there are actually four, if you include icons. Since the focus of this article is how to keep your hands on the keyboard, I was going to skip that one. </p>
<p><strong></p>
<p>Key Bindings<br />
</strong>Key bindings are the fastest way to launch an operation. They can be pressed at any time while editing. A key binding associates a key sequence with a command. A key sequence is a series of key strokes. Anything you do frequently should be bound to an easily remembered key sequence.</p>
<p>For example the key sequence Ctrl+A means hold down the Control key, typically labeled “Ctrl” on most keyboards, and press the A key. The letter A is represented as an uppercase letter, but this does not mean that you are to press the Shift key. If you are supposed to press the Shift key, the sequence will be written as Ctrl+Shift+A.  We use the uppercase A to match the letter on the keyboard.</p>
<p><strong></p>
<p>Commands<br />
</strong>Commands are useful for less frequently used operations or operations that take arguments. They are executed from the SlickEdit command line and are nearly as fast as key bindings. Press the Escape key (in most emulations) to activate the command line, which is displayed at the bottom of the SlickEdit application window.  </p>
<p style="text-align: center">
<p align="center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image001.jpg" title="image001.jpg"><img width="96" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image001.thumbnail.jpg" alt="image001.jpg" height="73" class="imageframe imgalignleft" /></a> </p>
<p align="center">  <em>Figure 1, SlickEdit with Command Line</em></p>
<p>It offers a full command history and completions for command names and arguments. Use the arrow keys or the mouse to scroll through previous commands. As you type, a list of possible completions is displayed. Use the arrow keys or mouse to select a completion. SlickEdit stores recorded macros as commands. You can also use Slick-C to write new commands. Use the <strong>_command</strong> keyword to identify a macro as a command. Any command can be bound to a key sequence for faster launching. </p>
<p><strong></p>
<p>Menus<br />
</strong>Menus are accessed via the mouse or a keyboard shortcut. Menus are great for infrequently used items that may not be worth a key binding. They are also helpful to learn about new capabilities. But if you use an operation frequently, you will be more productive by binding it to a key sequence or launching it from the command line. Many menus list a keyboard shortcut to launch the operation. This is just the key binding for the associated command. So when you use a keyboard shortcut, you are really just using a key binding. </p>
<p>You can also operate the main menu through hotkeys. Enable the use of hotkeys by selecting <strong>Tools &gt; Options &gt; General</strong>, selecting the General tab, and putting a check in “Alt menu hotkeys”. This will be selected by default in many emulations. Once enabled, pressing the Alt key will display an underscore beneath each menu option, indicating the letter to press to activate that option. This is not as fast as key bindings, but it does keep your hands on the keyboard and is much faster than using the mouse. In some cases the menu hot key sequence is a good mnemonic for the command. For example, Alt+P, E (to bring up <strong><u>P</u>roject &gt; Prop<u>e</u>rties</strong>) may be easier to remember and type than binding project-edit to Ctrl plus some function key. </p>
<p><strong></p>
<p>Icons<br />
</strong>SlickEdit presents icons in a series of toolbars related to different tasks. Toolbars can be customized with an extensive set of additional icons. Icons are useful for die-hard mouse users or for setting up infrequently used operations for which you have a hard time remembering the associated command or key binding. </p>
<p><strong></p>
<p>The Golden Triangle<br />
</strong>The three methods (excluding icons) to launch an operation are related, forming the Golden Triangle of operation launching. If you know how to execute an operation with one of these, you can easily configure SlickEdit to launch the operation using the other two methods. Commands form the base for the other two…which is why it is shown as the apex of the triangle (Damn it, Jim, I’m an engineer, not an artist!). Maybe I should have used a Golden U or something. <br />
 </p>
<p style="text-align: center">
<p align="center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.jpg" title="image003.jpg"><img width="128" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.thumbnail.jpg" alt="image003.jpg" height="91" class="imageframe imgalignleft" /></a></p>
<p align="center"><em>Figure 2 the Golden Triangle; behold its majesty!</em></p>
<p align="center">
<p align="center">
<p><strong>From Key Binding to Command<br />
</strong>Sometimes you may want to change the key sequence to which an operation is bound. You first need to find the command associated with that key sequence. Use the <strong>what-is</strong> command from the SlickEdit command line or select <strong>Help &gt; What Is Key</strong> from the main menu. The command line will be replaced with the prompt, “What is key:” Enter the key sequence in question, like Ctrl+A (hold down the Control key and press A), and SlickEdit displays the associated command. In CUA emulation, SlickEdit will output, “Ctrl+A runs the command select-all”. You can use the same approach to determine the commands associated with mouse events. After you run what-is, click any mouse button and you will be prompted with a list of mouse events. Select one from the list and SlickEdit displays the associated command. For example, if you select mbutton-down in CUA emulation, SlickEdit will output, “MButtonDn runs the command mou-paste”. </p>
<p><strong></p>
<p>From Command to Key Binding<br />
</strong>To find the key binding for a command, use the where-is command or select Tools &gt; Options &gt; Key Bindings from the main menu. The where-is command works just like what-is, except you type in the command name and it outputs the key sequence. The Key Bindings dialog displays a list of the commands. You can scroll through the list or search for a command by typing the command in the text box at the top. The key binding for the selected command is displayed in the dialog.   </p>
<p style="text-align: center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.jpg" title="image003.jpg"></a><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image005.png" title="image005.png"><img width="128" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image005.thumbnail.png" alt="image005.png" height="89" class="imageframe imgalignleft" /></a></p>
<p align="center"><em>Figure 3, Key Bindings Dialog    </em></p>
<p align="center">
<p><strong>Modifying Key Bindings<br />
</strong>The Key Bindings dialog can also be used to set a key binding. Type the command in the Command field, or select one from the list. Then click the “Add Key or Mouse Click” button. Now type the key sequence you want to use. For example, to bind a command to Ctrl+A, hold down the Control key and press A. To bind a command to a mouse event, click any mouse button and then select the appropriate event from the list. When you are finished, click the <strong>Bind</strong> button. To exit the dialog, click <strong>Done</strong>.</p>
<p><strong></p>
<p>From Menu to Command<br />
</strong>If the menu entry displays a keyboard shortcut, you can quickly find the associated command using what-is and entering the key sequence. If the menu entry does not display a shortcut, then finding the command for an entry involves a little more work. </p>
<p>SlickEdit provides a convenient UI under <strong>Macro &gt; Menus</strong> that allows you to view and modify menus in SlickEdit. To find commands for the items on the main menu, select “_mdi_menu” from the list and then click the <strong>Open</strong> button. You are presented with a menu hierarchy that you can expand to find the menu entry in question. Once selected, information about the entry is displayed including the command executed. You can use this menu to add or change the shortcut for a menu item. Doing so has the same effect as using the Key Bindings dialog to bind the menu entry’s command to a key sequence.   </p>
<p style="text-align: center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.jpg" title="image003.jpg"></a><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image005.png" title="image005.png"></a><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image007.jpg" title="image007.jpg"><img width="96" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image007.thumbnail.jpg" alt="image007.jpg" height="73" class="imageframe imgalignleft" /></a></p>
<p align="center"><em>Figure 4, Menu Editor</em></p>
<p>Some menu entries are added dynamically by SlickEdit, so you may have to search the code to find the associated command. One example of this is <strong>Build &gt; Java Options</strong>, which is only present when a Java project is active. Unfortunately, finding the associated commands for these entries can be very difficult and not easily covered in an article like this.</p>
<p><strong></p>
<p>Context Menus<br />
</strong>It is also easy to find the commands in the context menu for the editor window. The context menu, itself, contains an entry to “Edit This Menu”. Selecting this option brings up a dialog that lists the menu entries and associated information, including the command. Use this dialog to modify the context menus. Note that there are two context menus for the editor window: one when a selection is made and one when no selection is made. You can view or change the function that is used for these menus by selecting <strong>Tools &gt; Options &gt; File Extension Setup</strong> and selecting the Advanced tab.<br />
<strong></p>
<p>From Key Binding to Menu and Back<br />
</strong>Menu entries map to key bindings through commands, so key bindings are not directly associated with menu entries. To map from a key binding to a menu or vice versa, you need to look up the associated command. That Golden U is looking better all the time!</p>
<p><strong></p>
<p>Customizing Toolbar Icons<br />
</strong>The focus of this article has been to help you keep your hands on the keyboard, so icons weren’t included in the Golden Triangle. Besides, then I would have needed a Golden Square or some other form of rhombus, and that just doesn’t sound cool. You may find it helpful to change the set of displayed toolbars, add or remove icons, or change the behavior for an icon. SlickEdit uses the term “toolbar” to refer to both icon bars and tool windows. To change the set of displayed toolbars, select <strong>View &gt; Toolbars</strong> and check/uncheck one of the listed toolbars. </p>
<p>The list is divided into two groups. The top group is comprised of tool windows, like the Symbol view and the Projects view. The bottom group is made up of icon bars. </p>
<p>Additional options are available on the Toolbar Customization dialog by selecting <strong>View &gt; Toolbars &gt; Customize</strong>. The Toolbars tab provides a way to control the visibility of the toolbars. The Toolbars tab allows you to set options for which toolbars are visible, whether they are dockable, etc. </p>
<p>The Categories tab displays the complete set of available icons. These can be added to any icon toolbar by dragging them to the desired location. All of the icons have pre-defined behaviors, except the set in the “User Definable Tools” category. Use these to add your own functionality. </p>
<p>Each icon has an associated command that defines what happens when it is clicked. To view or change that command, right-click on the icon and select Properties. The icon needs to be located in a toolbar to do this. You cannot access the properties for an icon in the Toolbar Customizations dialog.  </p>
<p><strong></p>
<p>“Exit, Stage Left”<br />
</strong>OK, that one is a Snagglepuss reference<a name="_ednref2" title="_ednref2"></a>[ii]. Whatever angst I previously expressed for mice has now been transferred to the Golden Polygon of Unspecified Dimensions. Regardless of the shape, you now have the tools you need to configure SlickEdit to work the way YOU think it should, using the key bindings you find natural. This is one of the essential steps in being a true power programmer.<br />
 </p>
<hr />    </p>
<p class="MsoEndnoteText"><a name="_edn1" title="_edn1"></a>[i] Mr. Jinks, sometimes called “Jinks the cat”, appeared in the “Pixie and Dixie” cartoons as part of “The Huckleberry Hound Show”, by Hanna and Barbera.</p>
<p class="MsoEndnoteText"><a name="_edn2" title="_edn2"></a>[ii] Snagglepus is another of Hanna-Barbera’s cartoon characters.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2010%2F05%2Fkey-binding-command-menu-the-golden-triangle%2F';
  addthis_title  = 'Key+Binding%2C+Command%2C+Menu%3A+The+Golden+Triangle';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2010/05/key-binding-command-menu-the-golden-triangle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improve Slow Menu Response</title>
		<link>http://blog.slickedit.com/2010/01/improve-slow-menu-response/</link>
		<comments>http://blog.slickedit.com/2010/01/improve-slow-menu-response/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 20:25:10 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=415</guid>
		<description><![CDATA[Sometimes when you have a project with a large number of makefiles, you may notice that menus are slow to respond. This happens because SlickEdit collects the names of all the targets in each makefile and adds them to menus for build purposes (whether or not you are using SlickEdit to build). To resolve this [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Sometimes when you have a project with a large number of makefiles, you may notice that menus are slow to respond. This happens because SlickEdit collects the names of all the targets in each makefile and adds them to menus for build purposes (whether or not you are using SlickEdit to build). To resolve this issue, change the def_show_makefile_target_menu configuration variable to either 0 or 2. The default value, 1, specifies that all makefile submenus are enabled. A value of 0 disables all makefile submenus (Build menu and Project tool window), and a value of 2 enables makefile submenus only in the Project tool window (Build menu makefile targets are disabled).</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">To change the value of a configuration variable, from the main menu, click Macro &gt; Set Macro Variable. Select the variable to change from the drop-down list, enter the value in the Value field, then click OK.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">NOTE This behavior will be changed in the next release so that despite the number of makefiles in your project, there will not be a slow-down in menu response times.</div>
<p>Sometimes when you have a project with a large number of makefiles, you may notice that menus are slow to respond. This happens because SlickEdit collects the names of all the targets in each makefile and adds them to menus for build purposes (whether or not you are using SlickEdit to build). To resolve this issue, change the def_show_makefile_target_menu configuration variable to either 0 or 2. The default value, 1, specifies that all makefile submenus are enabled. A value of 0 disables all makefile submenus (Build menu and Project tool window), and a value of 2 enables makefile submenus only in the Project tool window (Build menu makefile targets are disabled).</p>
<p>To change the value of a configuration variable, from the main menu, click Macro &gt; Set Macro Variable. Select the variable to change from the drop-down list, enter the value in the Value field, then click OK.</p>
<p>NOTE This behavior will be changed in the next release so that despite the number of makefiles in your project, there will not be a slow-down in menu response times.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2010%2F01%2Fimprove-slow-menu-response%2F';
  addthis_title  = 'Improve+Slow+Menu+Response';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2010/01/improve-slow-menu-response/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Aliases</title>
		<link>http://blog.slickedit.com/2009/11/aliases/</link>
		<comments>http://blog.slickedit.com/2009/11/aliases/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 15:10:22 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Aliases]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=409</guid>
		<description><![CDATA[Directory Aliases
If you&#8217;re constantly opening files from certain directories, create aliases for those directories to save time. To create a directory alias, from the main menu, click Tools &#62; Options, expand Editing and select Global Aliases. Click New, enter a short text snippet that you can easily remember for the Alias Name, then click OK. [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Directory Aliases</strong></p>
<p>If you&#8217;re constantly opening files from certain directories, create aliases for those directories to save time. To create a directory alias, from the main menu, click <strong>Tools &gt; Option</strong>s, expand Editing and select Global Aliases. Click New, enter a short text snippet that you can easily remember for the Alias Name, then click OK. Back on the Options dialog, select the new alias, then enter the complete directory path for the alias in the text box on the right.  Click OK on the Options dialog. Now you can use the alias in directory fields on various dialogs in SlickEdit (like File &gt; Open): simply type the Alias Name and press Ctrl+Space to expand it.</p>
<p><strong>Language-Specific Aliases</strong></p>
<p>Language-specific aliases are similar to directory aliases except they can be used in edit windows for any frequently used text, like comment headers and language structures.</p>
<p><strong> </strong></p>
<p><strong></p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">To create a language-specific alias, from the main menu, click Tools &gt; Options &gt; Languages, expand your language category and language, then select Aliases. On the Alias option page, click New and enter a short text snippet that you can easily remember for the alias name, then click OK. Back on the Options dialog, select the new alias, then enter the text substitution for the alias in the text box on the right. Click OK on the Options dialog.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Now when you have a buffer or file open in that language, you can use the alias by typing the identifier and pressing Ctrl+SpaceLanguage-specific aliases are similar to [url="http://community.slickedit.com/index.php?topic=3399.0"]directory aliases[/url] except they can be used in edit windows for any frequently used text, like comment headers and language structures.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">To create a language-specific alias, from the main menu, click Tools &gt; Options &gt; Languages, expand your language category and language, then select Aliases. On the Alias option page, click New and enter a short text snippet that you can easily remember for the alias name, then click OK. Back on the Options dialog, select the new alias, then enter the text substitution for the alias in the text box on the right. Click OK on the Options dialog.</div>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Now when you have a buffer or file open in that language, you can use the alias by typing the identifier and pressing Ctrl+Space.</div>
<p></strong></p>
<p>To create a language-specific alias, from the main menu, click <strong>Tools &gt; Options &gt; Languages</strong>, expand your language category and language, then select Aliases. On the Alias option page, click New and enter a short text snippet that you can easily remember for the alias name, then click OK. Back on the Options dialog, select the new alias, then enter the text substitution for the alias in the text box on the right. Click OK on the Options dialog.</p>
<p>Now when you have a buffer or file open in that language, you can use the alias by typing the identifier and pressing Ctrl+Space.</p>
<p><strong>Alias from Selection</strong></p>
<p>A quick way to create a language-specific alias is to create it from a selection. Select some text in the editor, then right-click and select Create Alias from the context menu. Enter a name for the alias and click OK. The Options dialog appears, open to the Language-Specific Alias Options for the current language, and showing the new alias. Click OK on the Options dialog.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F11%2Faliases%2F';
  addthis_title  = 'Aliases';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/11/aliases/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hey, Check Out My Slick New Editor!</title>
		<link>http://blog.slickedit.com/2009/09/hey-check-out-my-slick-new-editor/</link>
		<comments>http://blog.slickedit.com/2009/09/hey-check-out-my-slick-new-editor/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 14:21:01 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Code Editors]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[SlickEdit Products]]></category>
		<category><![CDATA[Diffzilla]]></category>
		<category><![CDATA[Macro Record/Playback]]></category>
		<category><![CDATA[Refactoring]]></category>
		<category><![CDATA[Regular Expressions]]></category>
		<category><![CDATA[slickedit]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=396</guid>
		<description><![CDATA[Greg Christopher of VMware has written an article for DevX.com: Hey, Check Out My Slick New Editor!
In the article he discussing some of his favorite features of SlickEdit and why SlickEdit is his code editor of choice for programming.
On objections on switching editors
If your current editor works well enough for you, why switch? The answer depends [...]]]></description>
			<content:encoded><![CDATA[<p>Greg Christopher of VMware has written an article for DevX.com: <a href="http://www.devx.com/enterprise/Article/42874/0/page/1"><strong>Hey, Check Out My Slick New Editor!</strong></a></p>
<p>In the article he discussing some of his favorite features of SlickEdit and why SlickEdit is his code editor of choice for programming.</p>
<p><strong>On objections on switching editors</strong></p>
<blockquote><p>If your current editor works well enough for you, why switch? The answer depends on how you define &#8220;well enough.&#8221; Your current editor probably handles every editing command you think you need now, but consider the possibility that something could make you far more productive. You&#8217;ll see a few examples in a moment, but first, here are some of the reasons you might decide not to switch editors.</p></blockquote>
<p><span id="more-396"></span> <strong>Regular Expression Search and Replace</strong></p>
<blockquote><p>This isn&#8217;t an exclusive SlickEdit feature, some other editors have it too; but if you haven&#8217;t had the opportunity to experience regular expression searches, you should really consider switching to an editor that supports the feature.</p></blockquote>
<p><strong>Macro Record/Playback</strong></p>
<blockquote><p>SlickEdit carries out many of its commands through its slick-C programming language (note that both Brief and Emacs have their own languages as well). SlickEdit lets you write your own macros, or do a simple record / playback. This comes in handy when the syntax for find and replace gets too dicey.</p></blockquote>
<p><strong>Other Features</strong></p>
<blockquote><p>As you might imagine, because SlickEdit&#8217;s been around for 20 years, this article just scratches the surface.</p></blockquote>
<p>Continue reading <a href="http://www.devx.com/enterprise/Article/42874/0/page/1">Hey, Check Out My Slick New Editor<strong>!</strong></a> here: <a href="http://www.devx.com/enterprise/Article/42874/0/page/1">http://www.devx.com/enterprise/Article/42874/0/page/1 </a></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F09%2Fhey-check-out-my-slick-new-editor%2F';
  addthis_title  = 'Hey%2C+Check+Out+My+Slick+New+Editor%21';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/09/hey-check-out-my-slick-new-editor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating SlickEdit with Snow Leopard Services</title>
		<link>http://blog.slickedit.com/2009/09/automating-slickedit-with-snow-leopard-services/</link>
		<comments>http://blog.slickedit.com/2009/09/automating-slickedit-with-snow-leopard-services/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 13:45:40 +0000</pubDate>
		<dc:creator>Matthew E</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[SlickEdit Products]]></category>
		<category><![CDATA[SlickEdit Mac]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=379</guid>
		<description><![CDATA[I have always liked the idea of the Services menu, but found it frustratingly crowded and not often helpful. And I always thought Automator had real potential, but I never really found a place for it in my day-to-day work. With the improvements to the Services menu in Snow Leopard, the combination of these features is wonderfully [...]]]></description>
			<content:encoded><![CDATA[<p>I have always liked the idea of the Services menu, but found it frustratingly crowded and not often helpful. And I always thought Automator had real potential, but I never really found a place for it in my day-to-day work. With the improvements to the Services menu in Snow Leopard, the combination of these features is wonderfully useful.</p>
<p>SlickEdit&#8217;s Slick-C macro language should be no stranger to our users, but many folks aren&#8217;t aware that macros can be called when SlickEdit is started. In this tutorial, I&#8217;ll demonstrate how to use Automator to create a simple text service for SlickEdit, using this macro call facility.<span id="more-379"></span></p>
<p>First, launch the <strong>Automator</strong> application and create a new service using the Service template. At the top of the new workflow, it should say <em>Service receives <strong>selected text</strong> in <strong>any application</strong></em>. Make sure <em>Replaces selected text</em> is <strong>not</strong><em> </em>checked.</p>
<p>From the library&#8217;s actions panel, select the <strong>Text &gt; New Text File </strong>action, and drag it into the workflow as the first item. Pick a name and location for the temporary file to be saved, and make sure <em>Replace existing files </em>is checked, or else you&#8217;ll receive an Automator error the second time you use the service. Select the Encoding to be (UTF-8).</p>
<p>From the library&#8217;s action panel, select the <strong>Utilities &gt; Run Shell Script</strong> action, and drag it into workflow as the second item. The shell should be set to the default of <strong>/bin/bash</strong>. Change the right-hand drop-down to read <em>Pass input <strong>as arguments</strong></em>.</p>
<p>Delete any existing text in the shell script editor. Add the following text as the first line.</p>
<pre>export VSLICKXNOPLUSNEWMSG="1"</pre>
<p>Switch to Finder, and navigate to the Applications directory. Highlight your SlickEdit application, and Control-Click the application, and select <em>Show Package Contents</em> from the context menu. Drill down to the <strong>Contents/slickedit/bin</strong>, highlight the <strong>vs </strong>executable, and drag this into the shell script editor. This will insert the full path to the executable in the script editor. Make sure it&#8217;s on a new line after the export line you just typed.<br />
Append the following right after vs, making sure the command is all one line.</p>
<pre>-#new-file "-#get $1"&amp;</pre>
<p>The full script should look like the following:</p>
<pre>export VSLICKXNOPLUSNEWMSG="1"
/Applications/SlickEditV1402.app/Contents/slickedit/bin/vs -#new-file "-#get $1"&amp;</pre>
<div id="attachment_380" class="wp-caption alignnone" style="width: 160px"><a href="http://blog.slickedit.com/wp-content/uploads/2009/09/AutomatorService.png"><img class="size-thumbnail wp-image-380" src="http://blog.slickedit.com/wp-content/uploads/2009/09/AutomatorService-150x150.png" alt="Automator Service" width="150" height="150" /></a><p class="wp-caption-text">Automator Service</p></div>
<p>Don&#8217;t forget the ampersand at the end of the second line. Save the service, (⌘+S), and give it the name &#8220;New SlickEdit File&#8221;.</p>
<p>Switch to another application, like Safari or TextEdit, highlight some text, and pull down the application&#8217;s services menu. Your new service should now be available in the menu in the Text category.</p>
<p>The SlickEdit &#8220;magic&#8221; is done with the <strong>-#</strong> arguments. These specify macros to be called when SlickEdit in invoked. Any SlickEdit macro command (defined with the <span style="color: #0000ff">_command</span> keyword in Slick-C) can be called. Surround the entire -# argument with quotes if the Slick-C command takes any parameters, like the <strong>get</strong> macro in this example.</p>
<p>You can create a similar service that will insert the text into the currently active document by simply removing the <strong>-#new-file</strong> argument.</p>
<p>By default, service workflows are saved under $HOME/Library/Services. You can remove the service by removing this file.</p>
<p>To rename a Service, select the workflow file under $HOME/Library/Services, Control-Click to bring up the context menu, and select Show Package Contents. Look for the <strong>Contents/Info.plist</strong> file, and open it in the Property List Editor application. Change the value of the <strong>Services/Item/Menu/Menu item title</strong> entry. You do not need to rename the workflow file itself.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F09%2Fautomating-slickedit-with-snow-leopard-services%2F';
  addthis_title  = 'Automating+SlickEdit+with+Snow+Leopard+Services';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/09/automating-slickedit-with-snow-leopard-services/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Diminishing the Role of Folklore in Software Development</title>
		<link>http://blog.slickedit.com/2009/09/diminishing-the-role-of-folklore-in-software-development/</link>
		<comments>http://blog.slickedit.com/2009/09/diminishing-the-role-of-folklore-in-software-development/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 13:45:52 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Dev Management]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=347</guid>
		<description><![CDATA[There&#8217;s a great old commercial for Tootsie Roll Tootsie Pops that reminds me a lot of what happens on most software projects. The commercial features a crudely drawn cartoon of a boy trying to figure out a vitally important question.
Boy: Mr. Turtle, how many licks does it take to get to the Tootsie Roll center [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a great old <a href="http://en.wikipedia.org/wiki/Tootsie_Pops">commercial for Tootsie Roll Tootsie Pops</a> that reminds me a lot of what happens on most software projects. The commercial features a crudely drawn cartoon of a boy trying to figure out a vitally important question.</p>
<p><strong>Boy</strong>: Mr. Turtle, how many licks does it take to get to the Tootsie Roll center of a Tootsie Pop?<br />
<strong>Mr. Turtle</strong>: I&#8217;ve never even made it without biting. Ask Mr. Owl.<br />
<strong>Boy</strong>: Mr. Owl, how many licks does it take to get to the Tootsie Roll center of a Tootsie Pop?<br />
<strong>Mr. Owl</strong>: Let&#8217;s find out. A One&#8230; A two-HOO&#8230;A three.<br />
(crunch sound effect)<br />
<strong>Mr. Owl</strong>: Three!</p>
<p>This illustrates two common problems in oral communication. The first is the iterative process of finding someone who might know the answer to your question. In software development, the questions are typically of a more concrete nature, relating to a specific design or implementation choice.<span id="more-347"></span></p>
<p>Most software projects depend on a great deal of local knowledge. This is knowledge that is specific to the project, something you couldn&#8217;t know prior to working on the project. This include things like architectural and design details. The local knowledge is rarely written down in an organized manner but is contained in the collective experience of the development team. Because it isn&#8217;t written down and cataloged it cannot be searched, except through the iterative query process.</p>
<p>The other problem that this commercial illustrates is that of false experts. Like Mr. Owl, you will find people who will give you a definitive answer but one that is, unfortunately, wrong. In software development, it can be very difficult to spot these wrong answers&#8211;you don&#8217;t get to see someone just bite into the Tootsie Pop to come up with it.</p>
<p>In some cases, the person may truly believe the answer they give, and we&#8217;ll assume that until we have proof to the contrary. At other times, people just don&#8217;t like to admit that they don&#8217;t know something. So, they make up an answer. In either case, the damage to your work is just as bad. </p>
<p>Folklore is typified by this kind of oral communication. It is the main method for communicating important information in primitive cultures. Knowledge is passed from one person to another. Often, because of miscommunication, the knowledge is corrupted by each successive telling. </p>
<p>It&#8217;s like that <a href="http://en.wikipedia.org/wiki/Chinese_whispers">party game where you start off with a sentence and have each person whisper it to another person</a>. This is repeated several times and then the last person writes down the sentence. In the end, the meaning of the sentence is often radically changed with comical results. The same thing happens in software development, but the results are far less comical.</p>
<p>The solution to both of these problems is to document local knowledge. One form of that is code comments. So much has been written on that topic, that I don&#8217;t feel the need to add more. However, many things are not appropriate to store in code comments. It&#8217;s that kind of knowledge that is most often passed along as folklore.</p>
<p>Fortunately, technology has given us a solution. A <a href="http://en.wikipedia.org/wiki/Wiki">wiki </a>provides a centralized knowledge repository that is edited by the group. This allows for the information to be easily reviewed for accuracy. It also eliminates the need to wander around and find someone who might know the answer to your question.</p>
<p>It also addresses another problem. Many people are hesitant to go ask questions. Either they are afraid of looking stupid, or they don&#8217;t want to trouble their coworkers. So, they will often flounder around trying to figure it out on their own, wasting time, or they will try to make due without the answer. A wiki allows people to find an answer without the potential embarrassment of exposing their ignorance. </p>
<p>To be successful, a wiki needs to be searchable and browseable. The search capability is needed to find the answer to specific questions. Browseability allows someone to view a set of topics and delve deeper to get more information. This is important to allow someone to gain the initial knowledge on a topic, particularly for getting new team members up to speed.  Most packages do a good job providing the search capability. But very few provide a good mechanism to build a browseable knowledge structure. </p>
<p>At SlickEdit, we use <a href="http://www.mediawiki.org/wiki/MediaWiki">MediaWiki </a>for our shared knowledge. It provides both an excellent search and a convenient means to organize topics. The side menu allows you to structure your top-level categories, and each page automatically includes a table of contents if it contains 4 or more subsections. This makes it simple to build a logical knowledge decomposition. It&#8217;s this capability to create a browseable structure that sets MediaWiki apart from other wiki software we tried. </p>
<p>Finding the right wiki software and setting up an initial structure is only the first step, though. The main challenge is getting the team to populate it. You face a couple of common problems here. </p>
<p>The first is the normal reluctance of programmers to document things. Many programmers despise any activity that is not directly related to producing code. This is a tough nut to crack, since this attitude is often deeply ingrained in the developers psyche. How you overcome this depends on the person and the arguments that they will listen to. You can appeal to their sense of professionalism and explain that this is part of professional development. You can appeal to their sense of teamwork and explain how this helps make the team more effective. You will need your full set of management skills to get everyone contributing.</p>
<p>Even if everyone is willing to contribute, one problem that often prevents a wiki from reaching its true potential is that of obviousness. Once you know something, it seems obvious to you. If it&#8217;s obvious, then why document it? This same problem plagues code comments. The best solution is to make the wiki an essential part of the problem solving process. When someone is trying to answer a question, they should look in the wiki. If they don&#8217;t find the answer, they should make a note to come back and add this information to the wiki after folklore has delivered an answer. </p>
<p>So, how does having a wiki alter the scenario depicted in the commercial?<br />
<strong>Boy</strong>: Hmm, I wonder how many licks does it take to get to the Tootsie Roll center of a Tootsie Pop?<br />
(Boy looks in wiki for the answer and finds an entry by Mr. Owl: &#8220;How many licks does it take to get to the Tootsie Roll center of a Tootsie Pop?  Three.&#8221;)</p>
<p>Well, at least he didn&#8217;t have to go bother curmudgeonly, old Mr. Turtle.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F09%2Fdiminishing-the-role-of-folklore-in-software-development%2F';
  addthis_title  = 'Diminishing+the+Role+of+Folklore+in+Software+Development';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/09/diminishing-the-role-of-folklore-in-software-development/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>My Economic Stimulus Plan: Cash for Clunky Editors</title>
		<link>http://blog.slickedit.com/2009/08/my-economic-stimulus-plan-cash-for-clunky-editors/</link>
		<comments>http://blog.slickedit.com/2009/08/my-economic-stimulus-plan-cash-for-clunky-editors/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 16:52:59 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Code Editors]]></category>
		<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=339</guid>
		<description><![CDATA[As part of the economic stimulus package, the government has instituted a Cash for Clunkers program that pays people to trade in older, less fuel-efficient cars for new, more fuel-efficient ones. $1 billion was made available for this program, and it was quickly used up. So, Congress is debating allocating even more money. While the [...]]]></description>
			<content:encoded><![CDATA[<p>As part of the economic stimulus package, the government has instituted a Cash for Clunkers program that pays people to trade in older, less fuel-efficient cars for new, more fuel-efficient ones. $1 billion was made available for this program, and it was quickly used up. So, Congress is debating allocating even more money. While the government is in such a giving mood, I&#8217;d like to see a Cash for Clunky Editors program that pays people to trade in their current, less effective editor on a new, more powerful editor.</p>
<p>In terms of economic stimulus, this could have a much greater effect on the nation. Consider that many programmers use minimalist editors that provide little help to analyze and navigate their code, don&#8217;t include powerful completions, or features to cut the number of keystrokes necessary to type their code. If these programmers switched to a more powerful editor, like&#8230;oh, let&#8217;s say, SlickEdit&#8230;their productivity would go way up.<span id="more-339"></span></p>
<p>As the productivity of the individual programmers goes up, their projects would get done earlier or include more capabilities. This increases the productivity of the people using that software, which would then increase the profitability of those companies. Since software underlies almost every industry, this could lead to a potential boom, the likes of which hasn&#8217;t been seen since the post-WWII expansion. Suddenly, there&#8217;s a surge in the US GDP. We pay off the national debt in a few years and have money left over for a comprehensive public health care system.</p>
<p>And it all begins with getting people to switch to a more effective editor.</p>
<p>Unfortunately, SlickEdit isn&#8217;t big enough to warrant a special government program like this. We&#8217;re not one of those too-big-to-fail kind of companies. But that doesn&#8217;t mean you can&#8217;t experience your own little economic stimulus.</p>
<p>Look at your coding practices and see if a more powerful editor wouldn&#8217;t help you write more code faster with fewer errors. Though the government won&#8217;t pay you for switching, the boost in productivity surely will.</p>
<p><strong><br />
SlickEdit is Giving Cash for your Clunky Editor!<br />
<em>Cash for Clunky Editors Program:</em></strong></p>
<p>If the editor you purchased is lacking the <em>speed, power, and flexibility</em> SlickEdit provides…trade it in for CASH towards SlickEdit.  Call <strong>1-800-934-EDIT (3348)</strong> or email <a href="mailto:sales@slickedit.com">sales@slickedit.com</a>, and mention the Cash for Clunky Editors Program to learn about the savings.</p>
<p>The program expires on September 30<sup>th</sup>, 2009, so act quickly.</p>
<p>Happy coding,<br />
The SlickEdit Team</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F08%2Fmy-economic-stimulus-plan-cash-for-clunky-editors%2F';
  addthis_title  = 'My+Economic+Stimulus+Plan%3A+Cash+for+Clunky+Editors';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/08/my-economic-stimulus-plan-cash-for-clunky-editors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The SlickEdit Command Line</title>
		<link>http://blog.slickedit.com/2009/06/the-slickedit-command-line/</link>
		<comments>http://blog.slickedit.com/2009/06/the-slickedit-command-line/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 17:08:33 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[slickedit]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=325</guid>
		<description><![CDATA[Use SlickEdit commands instead of the mouse to save time as you work. Open the SlickEdit command line by pressing Esc (in most emulations), type the command and any options, then press Enter. If you use a command frequently, bind it to a keyboard shortcut to save even more time. Type “Slickedit command line” in [...]]]></description>
			<content:encoded><![CDATA[<p>Use SlickEdit commands instead of the mouse to save time as you work. Open the SlickEdit command line by pressing <strong>Esc</strong> (in most emulations), type the command and any options, then press Enter. If you use a command frequently, bind it to a keyboard shortcut to save even more time. Type “Slickedit command line” in the Help Index (<strong>Help &gt; Index</strong>) to learn more.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F06%2Fthe-slickedit-command-line%2F';
  addthis_title  = 'The+SlickEdit+Command+Line';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/06/the-slickedit-command-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why does SlickEdit insert “/**/” when I type “/*” ?</title>
		<link>http://blog.slickedit.com/2009/06/why-does-slickedit-insert-%e2%80%9c%e2%80%9d-when-i-type-%e2%80%9c%e2%80%9d/</link>
		<comments>http://blog.slickedit.com/2009/06/why-does-slickedit-insert-%e2%80%9c%e2%80%9d-when-i-type-%e2%80%9c%e2%80%9d/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 15:17:52 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=323</guid>
		<description><![CDATA[This is to make it possible to create a multi-line comment without temporarily commenting out all the code from the /* to the end of the file or to the end of  the next already existing multi-line comment.  This makes it possible to keep your file in a syntacticly correct state.  This allows you to [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #29303b; font-family: Arial; font-size: 12px; line-height: 18px; text-align: left;">This is to make it possible to create a multi-line comment without temporarily commenting out all the code from the /* to the end of the file or to the end of  the next already existing multi-line comment.  This makes it possible to keep your file in a syntacticly correct state.  This allows you to use things like tag navigation or statement navigation to move to the location where you want to end the comment.  When you type */ in order to close the comment, the editor will search backwards for a matching /**/ and patch things up by deleting the */ characters.  The unique thing about this technique is that it gives you the benefit of keeping your code syntactically correct without actually changing what you type to create a comment at all.  You still type /*, then move your cursor down, then type */, just like you did before.</span></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F06%2Fwhy-does-slickedit-insert-%25e2%2580%259c%25e2%2580%259d-when-i-type-%25e2%2580%259c%25e2%2580%259d%2F';
  addthis_title  = 'Why+does+SlickEdit+insert+%E2%80%9C%2F%2A%2A%2F%E2%80%9D+when+I+type+%E2%80%9C%2F%2A%E2%80%9D+%3F';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/06/why-does-slickedit-insert-%e2%80%9c%e2%80%9d-when-i-type-%e2%80%9c%e2%80%9d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clipboard Formats</title>
		<link>http://blog.slickedit.com/2009/06/clipboard-formats/</link>
		<comments>http://blog.slickedit.com/2009/06/clipboard-formats/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 14:05:48 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=319</guid>
		<description><![CDATA[SlickEdit supports RTF and HTML clipboard formats for Windows. This means you can paste formatted and color-coded text from SlickEdit into other applications. The HTML clipboard format type is enabled by default. You can change to the RTF format or turn the feature off completely using the Clipboard formats option (located at Tools &#62; Options [...]]]></description>
			<content:encoded><![CDATA[<p>SlickEdit supports RTF and HTML clipboard formats for Windows. This means you can paste formatted and color-coded text from SlickEdit into other applications. The HTML clipboard format type is enabled by default. You can change to the RTF format or turn the feature off completely using the <strong>Clipboard formats</strong> option (located at <strong>Tools &gt; Options &gt; Editing &gt; Selections</strong>).</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F06%2Fclipboard-formats%2F';
  addthis_title  = 'Clipboard+Formats';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/06/clipboard-formats/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8230;But It&#8217;s More Fun to Reinvent the Wheel</title>
		<link>http://blog.slickedit.com/2009/06/but-its-more-fun-to-reinvent-the-wheel/</link>
		<comments>http://blog.slickedit.com/2009/06/but-its-more-fun-to-reinvent-the-wheel/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 17:17:44 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=309</guid>
		<description><![CDATA[&#8220;Reinventing the wheel&#8221; is used as a common metaphor in software development for rewriting code that has already been written. For example, SlickEdit contains a number of features that traverse directories and process files, including Find in Files, DIFFzilla, Add Tree, and more. In each case the syntax used to exlclude files or directories is [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Reinventing the wheel&#8221; is used as a common metaphor in software development for rewriting code that has already been written. For example, SlickEdit contains a number of features that traverse directories and process files, including Find in Files, DIFFzilla, Add Tree, and more. In each case the syntax used to exlclude files or directories is different. Sometimes the exclude specs are space delimited; sometimes they are delimited with semi-colons. Some require the use of asterisks to specify a directory; some don&#8217;t.</p>
<p>The basic reason for this is that each feature was written in isolation without finding and reusing the capabilities of the other features. This is a very common problem on most software projects. To address this issue, I believe that software development should be broken down into two different workflows: mechanism application and mechanism creation.</p>
<p>We can define a mechanism as a component with a cohesive set of functionality, like the wheel. In most cases, mechanisms are meant to be reusable, though it is possible that there will be only one use for that mechanism in a particular program. Common mechanisms in software include login processors, calendar widgets, and sorted lists. These elements perform a specific function that is independent of what they are used for.</p>
<p>Mechanisms can also be specific solutions to common design problems, like error logging, object persistence, and thread synchronization. Ideally, these would be encapsulated in a library that is used by other developers, but in some instances it is more a matter of following a specified convention.</p>
<p>For example, one project I worked on specified that each function would contain #ifdefs for tracing and logging with specific information that each function should output. This still represents a mechanism that defines a cohesive functionality, in this case, tracing. But instead of writing a reusable library, the mechanism was primarily a set of conventions we all followed when writing our functions.</p>
<p>During mechanism application, the specialized functionality of a feature is built using existing mechanisms. You can work on your own unless you have a question about the specs or need assistance from another developer. The code being written is unique to the feature, so little attention is given to reuse unless a new mechanism is needed. Then you enter mechanism creation.</p>
<p>During mechanism creation, you are developing a generalized capability that is specifically intended to be reusable. This requires a totally different workflow. You have to stop and do a degree of analysis before you create the new mechanism. Several questions need to be answered. Are you sure there isn&#8217;t already a mechanism for this? If not, what are the essential behaviors of this mechanism? Where should it be stored?</p>
<p>These questions are best addressed with other members of the team. The goal is to produce a mechanism that can be used by everyone, not just by you. So, you need to get their input to make sure it does more than meet your immediate needs, or at least doesn&#8217;t prevent someone from extending it in the future.</p>
<p>When a developer tackles the new mechanism as part of their normal development, two common problems occur. Often the programmer includes the mechanism as part of the feature-specific code, rather than placing the mechanism into the library where others can find it. Even when they do put the code in the proper place, it often is written in such a way that it is only useful for this feature. You can&#8217;t make it reusable without breaking the feature that already depends on it.</p>
<p>In most applications, mechanism application is very straightforward, simple programming and requires little creativity. Mechanism creation, on the other hand, requires a great deal of creativity and design effort. You have to think more about algorithms and efficiency.</p>
<p>So why don&#8217;t programmers naturally break their work into these separate workflows? I think there are a number of explanations.</p>
<p>First, I think programmers get very focused on completing a feature. If they have to interrupt that work to enter the slower and more deliberate workflow required to create a new mechanism, then it delays the attainment of their goal.</p>
<p>Secondly, programmers like to program. Designing reusable components requires meetings, documentation, and reviews&#8211;all of which get in the way of programming.</p>
<p>Thirdly, most programmers aren&#8217;t too keen on collaboration. When you talk things over in a group, you have a chance of not getting your way. If you just build it yourself, you can do it the way you think it should be done.</p>
<p>Finally, by separating the two workflows, the creation of a needed mechanism might be assigned to a different programmer. Since the creation of these mechanisms is often more challenging and, therefore, more fun; developers are hesitant to initiate a workflow that would potentially deprive them of this fun.</p>
<p>Basically, it&#8217;s more fun to reinvent the wheel than to determine whether a suitable wheel already exists. If the wheel does need to be invented, it&#8217;s less fun to do it with a committee of your peers who may disagree with your vision for the wheel.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F06%2Fbut-its-more-fun-to-reinvent-the-wheel%2F';
  addthis_title  = '%26%238230%3BBut+It%26%238217%3Bs+More+Fun+to+Reinvent+the+Wheel';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/06/but-its-more-fun-to-reinvent-the-wheel/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>S-Expression Navigation</title>
		<link>http://blog.slickedit.com/2009/05/s-expression-navigation/</link>
		<comments>http://blog.slickedit.com/2009/05/s-expression-navigation/#comments</comments>
		<pubDate>Mon, 11 May 2009 16:40:13 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=294</guid>
		<description><![CDATA[Commands (and key bindings) are available for Emacs-like S-expression navigation. These work in all emulations.

The next_sexp (Ctrl+Alt+Right) and prev_sexp (Ctrl+Alt+Left) commands can be compared to next_word and prev_word, except that they treat blocks as words.
 The backward_up_sexp (Ctrl+Alt+Up) command is the shortcut for navigating to the start of the immediately enclosing block (in Lisp, this would be the [...]]]></description>
			<content:encoded><![CDATA[<p>Commands (and key bindings) are available for Emacs-like S-expression navigation. These work in all emulations.</p>
<ul>
<li>The <strong>next_sexp</strong> (Ctrl+Alt+Right) and <strong>prev_sexp</strong> (Ctrl+Alt+Left) commands can be compared to <strong>next_word</strong> and <strong>prev_word</strong>, except that they treat blocks as words.</li>
<li> The <strong>backward_up_sexp</strong> (Ctrl+Alt+Up) command is the shortcut for navigating to the start of the immediately enclosing block (in Lisp, this would be the open paren).</li>
<li>The <strong>forward_down_sexp</strong> (Ctrl+Alt+Down) command is used to drill into a block. If the cursor is at the start of a block, it moves the cursor to the first S-expression within the block; otherwise, it behaves like next_sexp.</li>
<li>The commands <strong>select_prev_sexp</strong> (Ctrl+Alt+Shift+Left) and <strong>select_next_sexp</strong> (Ctrl+Alt+Shift+Right) extend a character selection from the cursor position to the start of the next or previous S-expression, respectively. Like the Shift+Cursor commands do to CUA style selections, if executed repeatedly, they will extend the current character selection.</li>
<li> The <strong>cut_prev_sexp</strong> (Ctrl+Alt+Backspace) command will delete the S-expression to the left of the cursor and copy it to the clipboard. Again, if called repeatedly, this will prepend the subsequent deletions to the clipboard.</li>
</ul>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F05%2Fs-expression-navigation%2F';
  addthis_title  = 'S-Expression+Navigation';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/05/s-expression-navigation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Beat Down an &#8220;else&#8221; Statement in Three Keystrokes</title>
		<link>http://blog.slickedit.com/2009/04/how-to-beat-down-an-else-statement-in-three-keystrokes/</link>
		<comments>http://blog.slickedit.com/2009/04/how-to-beat-down-an-else-statement-in-three-keystrokes/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 13:52:40 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=286</guid>
		<description><![CDATA[Suppose you want to get from something like this:
 
       if ( cond ) {
          doSomething();
       } else {
          goSomewhere();
          doSomethingElse();
          comeBack();
          takeANap();
       }
 
To this:
 
       if ( cond ) {
         [...]]]></description>
			<content:encoded><![CDATA[<div>Suppose you want to get from something like this:</div>
<div> </div>
<div>       if ( cond ) {</div>
<div>          doSomething();</div>
<div>       } else {</div>
<div>          goSomewhere();</div>
<div>          doSomethingElse();</div>
<div>          comeBack();</div>
<div>          takeANap();</div>
<div>       }</div>
<div> </div>
<div>To this:</div>
<div> </div>
<div>       if ( cond ) {</div>
<div>          doSomething();</div>
<div>       }</div>
<div>       goSomewhere();</div>
<div>       doSomethingElse();</div>
<div>       comeBack();</div>
<div>       takeANap();</div>
<p>
<div>
1. First, put your cursor on else and press Ctrl+Shift+Right to select it.</div>
<div>2. Press Enter.</div>
<div>3. Press Ctrl+Delete, and select Unsurround the code block.</div>
<p></p>
<div>Though Unsurround does not normally apply to else blocks, this example shows how you can manipulate your code to make a feature work for you in order to save time.</div>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F04%2Fhow-to-beat-down-an-else-statement-in-three-keystrokes%2F';
  addthis_title  = 'How+to+Beat+Down+an+%26%238220%3Belse%26%238221%3B+Statement+in+Three+Keystrokes';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/04/how-to-beat-down-an-else-statement-in-three-keystrokes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Want to Learn Vim?</title>
		<link>http://blog.slickedit.com/2009/04/want-to-learn-vim/</link>
		<comments>http://blog.slickedit.com/2009/04/want-to-learn-vim/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 15:09:07 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=268</guid>
		<description><![CDATA[Did You Know?
SlickEdit provides an emulation mode for the Vim text  editor. If you want to learn Vim, or need to hone your skills, you can use the vimtutor command. Most Vim installations come with  this command, which displays a special &#8220;learn-by-doing&#8221; practice file in the  editor that you can can actually [...]]]></description>
			<content:encoded><![CDATA[<p class="NormalText"><strong>Did You Know?</strong></p>
<p class="NormalText">SlickEdit provides an emulation mode for the Vim text  editor. If you want to learn Vim, or need to hone your skills, you can use the <span><strong class="command">vimtutor</strong></span> command. Most Vim installations come with  this command, which displays a special &#8220;learn-by-doing&#8221; practice file in the  editor that you can can actually edit as you learn how to use the Vim commands.  This file has been customized for SlickEdit users.</p>
<p class="NormalText">To use the command, open the SlickEdit command line, then  type the command and press <span><strong class="keycap">Enter</strong></span>. The  practice file is displayed in the editor. Each time you use the <span><strong class="command">vimtutor</strong></span> command, SlickEdit creates a fresh copy  of this file.</p>
<p class="NormalText">
<h3 class="admon">Tip</h3>
<p class="CellBody"> </p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p class="NormalText">You will be prompted to switch to the Vim emulation when you  invoke the command if the editor is set to a different emulation. </p>
</li>
<li>
<p class="NormalText">When in the Vim emulation, you can open the SlickEdit  command line with <span><strong class="keycap">Ctrl</strong></span>+<span><strong class="keycap">A</strong></span>, or in any emulation, by clicking in the message  area with the mouse. See <a>Activating the Command  Line</a> for more information.</p>
</li>
</ul>
</div>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2009%2F04%2Fwant-to-learn-vim%2F';
  addthis_title  = 'Want+to+Learn+Vim%3F';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2009/04/want-to-learn-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SlickEdit Macros for Everybody</title>
		<link>http://blog.slickedit.com/2008/11/slickedit-macros-for-everybody/</link>
		<comments>http://blog.slickedit.com/2008/11/slickedit-macros-for-everybody/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 15:34:06 +0000</pubDate>
		<dc:creator>Jeffrey</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=254</guid>
		<description><![CDATA[I ran across a great blog the other day &#8220;SlickEdit Macros for Everybody&#8220;.  The blog is written by David Hicks, a self-proclaimed SlickEdit devotee, who enjoys &#8220;Squeezing as much functionality as possible out of his editor of choice.&#8221; He created the site because he likes working with Slick-C and felt there was not enough Slick-C code [...]]]></description>
			<content:encoded><![CDATA[<p>I ran across a great blog the other day &#8220;<a href="http://myslickeditmacros.blogspot.com/">SlickEdit Macros for Everybody</a>&#8220;.  The blog is written by David Hicks, a self-proclaimed SlickEdit devotee, who enjoys &#8220;Squeezing as much functionality as possible out of his editor of choice.&#8221; He created the site because he likes working with Slick-C and felt there was not enough Slick-C code on the web.</p>
<p>Slick-C is a macro programming language upon which the SlickEdit code editor is based.  Slick-C allows developers to modify the look and feel of the editor, write macros to perform custom operations, add new language support, and essentially extend the editor’s functionality until it is completely customized according to your preferences.</p>
<p><a href="http://myslickeditmacros.blogspot.com/2008_09_04_archive.html">From his first post</a>:</p>
<blockquote><p>Here you&#8217;ll find Slick-C macros of all kinds, from overly simple to fairly complex. I&#8217;m a writer/editor/journalist by trade, not a professional developer. Slick-C programmers should find something 0f interest here, including plenty of code that can be tweaked or fixed.</p>
<p>The purpose of this blog is to address the shortage of Slick-C code on the Web, while stimulating discussion and encouraging code sharing.</p>
<p>I&#8217;ve used Slickedit in my daily work since approximately 1998. Currently I have 388 _command macros in my vusrmacs.e file. I&#8217;m sure there are other Slickedit users whose macro folders are wishing to burst free and benefit the larger community.</p>
<p>My professional roles are technical writer; editor and researcher of print and electronic publications; desktop publisher; journalist. My programming experience has generally been limited to high-level scripting languages. I&#8217;ve spent a lot of time using numerous text editors and macro languages. Of the two kinds of Slickedit users named in the subtitle of this blog, I&#8217;m a Wordsmith rather than a Code Maven.</p></blockquote>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F11%2Fslickedit-macros-for-everybody%2F';
  addthis_title  = 'SlickEdit+Macros+for+Everybody';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/11/slickedit-macros-for-everybody/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Too Busy Bailing to Plug the Leak</title>
		<link>http://blog.slickedit.com/2008/10/too-busy-bailing-to-plug-the-leak/</link>
		<comments>http://blog.slickedit.com/2008/10/too-busy-bailing-to-plug-the-leak/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 14:15:33 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Dev Management]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=250</guid>
		<description><![CDATA[My last post, Design Fail Patterns, dealt with the ways that people often select the wrong technologies for a project. That made me think of another way I&#8217;ve seen projects and people fail.
Cast your mind back to the days of the tall ships, great wooden vessels that plied the oceans under wind power. Imagine one [...]]]></description>
			<content:encoded><![CDATA[<p>My last post, <a href="http://blog.slickedit.com/?p=249">Design Fail Patterns</a>, dealt with the ways that people often select the wrong technologies for a project. That made me think of another way I&#8217;ve seen projects and people fail.</p>
<p>Cast your mind back to the days of the tall ships, great wooden vessels that plied the oceans under wind power. Imagine one of those majestic ships sailing along when suddenly it hits a reef, tearing a large hole below the waterline. All hands scramble to save the ship. They bail and bail, but the ship continues to sink. As the ship sinks lower, they bail more furiously until finally the ship is lost. The survivors are washed ashore on a nearby island.</p>
<p>As they stare out at the masts of the ship, still visible above the waves, the Captain asks, “Why weren’t we able to plug the leak?”</p>
<p>One of the crew pipes up, “Captain, sir, we were too busy bailing to plug the leak.”</p>
<p>OK, this is a contrived example, and it’s very hard to believe that it could occur in real life. However, very similar situations frequently arise in software development.</p>
<p><strong>Bad Codebase</strong></p>
<p>The most typical way I’ve seen this occur is on projects where the early work has set us up for failure. The infrastructural code is so full of bugs or badly designed that it has become a stumbling block to get the rest of the system built. The team furiously pounds away at the code, driving toward a critical milestone fixing bugs as they can. But with every iteration, things take longer to do and the codebase gets harder to work with.</p>
<p>In this case, the leak is the poor codebase. The only way to plug the leak is to rewrite that part of the system. Often, the programming team is unable to recognize that this code is a lost cause, particularly if they participated in its development. More commonly, the programmers know that this code is the problem, but they can’t talk management into the schedule slip that is necessary to fix it. In the end, the project takes longer to complete than if we had stopped and rewritten the offending code.</p>
<p>Unfortunately, a leak in software is rarely as visible or as easy to appreciate as a gaping hole in a hull. However, the programmers’ work to patch the system instead of fixing it is just as futile as the sailors who just keep bailing. And the result is nearly as predictable.</p>
<p><strong>Poor Process</strong></p>
<p>Another way this phenomenon is manifested is in adherence to bad processes. I worked on a project that used very poor configuration management techniques. The approach to version control was sloppy, and there were no controls for how integration servers were configured or how code was deployed for testing. Consequently, even though we would get successful tests on the integration server, we continually faced problems in production. These problems stemmed from several causes. Sometimes it was because of files that were edited on the integration server and not checked into source control, so they never got deployed to production. Or someone would set up the directory structure differently so that it would work on one machine but not the other.</p>
<p>When these problems appeared, the proffered solution was that people should be more careful. This case might be slightly different. Instead of thinking that you’re too busy bailing to plug the leak; in this case you believe that bailing may be all that’s needed.</p>
<p>I’m a firm believer that your test machines should mirror your production environment in every way possible and that you should deploy your code for testing exactly as it will be deployed to the production environment. And if I ever catch someone editing a file on a test or integration server, I’ll <a href="http://en.wikipedia.org/wiki/Keelhauling">keel haul</a> them!</p>
<p><strong>No Time for Personal Development</strong></p>
<p>I also see the “too busy bailing” mentality at work in peoples’ careers. As a hiring manager, I have interviewed hundreds of candidates for jobs over the years. I’m frequently amazed to learn how little people invest in their careers and the knowledge necessary to advance.</p>
<p>For example, most of my work has been on Object-Oriented projects. So, I typically ask OO questions of the candidates. One question is about how they learned OO programming. What books did they read? How did they hone this knowledge? Typically, I find that most candidates learned OO in college and have done nothing to build on that knowledge, other than their normal work experience.</p>
<p>I’ve also interviewed candidates for web development. So, I’ll get a resume from a bright young college student who is about to graduate. They tell me they want to be a web developer.</p>
<p>“Great!” I say. “So, have you ever built a website?”</p>
<p>“No.”</p>
<p>“Do you know HTML and JavaScript?”</p>
<p>“We had that in a class once.”</p>
<p>“Well, then what have you done to become a web developer?”</p>
<p>“I’m real busy with class right now.”</p>
<p>So, basically, this guy is looking for someone to pay him to become a web developer. I’ll always consider a new grad without formal experience, but I want someone who has done more than just sit through classes on their way to a degree. Show me some passion or interest in your area by working on something outside of class. Or at least have knowledge in the basic tools.</p>
<p><strong>Tool Selection</strong></p>
<p>The final way I see people being too busy bailing is through adherence to less effective tools. I often interact with people who have been using vi their whole career, or some other minimal editor, and just can’t be bothered to change. No amount of telling them how you can save them time will convince them to switch. They may even admit that they know they could be more productive if they switched, but they don’t want to take the time to learn a new tool.</p>
<p>Truthfully, this could be a case of the tool becoming the job rather than being too busy bailing. In that situation, a person spends so much time, say, hammering that they lose sight of why they are hammering: to build houses. So when a new way of driving nails comes along, they stick to their current way of working. “I’ve been hammering for 20 years. I’m not about to switch.”</p>
<p>Switching tools will always involve an investment in time. But if you pick the right tool, that investment will pay off rapidly.</p>
<p>So watch for signs of bailing in your own work and career. Consider whether there is a leak that needs to be plugged first. If not, then bail for all your worth. If you have spotted a leak and no one will listen, maybe you need to do a different kind of bailing.</p>
<p> </p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F10%2Ftoo-busy-bailing-to-plug-the-leak%2F';
  addthis_title  = 'Too+Busy+Bailing+to+Plug+the+Leak';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/10/too-busy-bailing-to-plug-the-leak/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Can we standardize version control?</title>
		<link>http://blog.slickedit.com/2008/09/can-we-standardize-version-control/</link>
		<comments>http://blog.slickedit.com/2008/09/can-we-standardize-version-control/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 12:45:41 +0000</pubDate>
		<dc:creator>Scott Hackett</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=247</guid>
		<description><![CDATA[There are an unbelievable number of version control systems out there.  They all have their strengths and weaknesses, and almost everyone has a strong opinion about which one is best.  These software tools weren&#8217;t written by some group of developers that were out of touch with their end users either.  They are all developer tools, [...]]]></description>
			<content:encoded><![CDATA[<p>There are an <a href="http://en.wikipedia.org/wiki/Comparison_of_revision_control_software">unbelievable number</a> of version control systems out there.  They all have their strengths and weaknesses, and almost everyone has a strong opinion about which one is best.  These software tools weren&#8217;t written by some group of developers that were out of touch with their end users either.  They are all developer tools, written by developers for developers.  Many of them were born from previous version control packages, such as how SVN evolved from CVS.  The purpose was to keep what was good about the previous system and redo what they felt was lacking.</p>
<p>At this point, we&#8217;re pretty far along in the evolution of version control development. However, there&#8217;s a fundamental problem with all of these version control systems.  Even though they set out to do the pretty much the same thing, there&#8217;s no common interface to any of them.  Even worse, the interpretation of common concepts are completely different.  It&#8217;s not noticeable if you&#8217;ve only used one.  The more you use, though, the more obvious it becomes.  The only attempt at such a thing that I can recall is Microsoft&#8217;s SCC interface.  Unfortunately, it served a very specific purpose and aimed for the lowest common denominator.</p>
<p>If you have ever tried to switch from one version control system to another, you have suffered through this.  If you&#8217;ve ever had to port the version history from one system to another, then you likely gave up and stuck with the old system or lost all of your history.  The interoperability of version control systems is horrendous.</p>
<p><strong>Standardized interpretation</strong></p>
<p>Let&#8217;s start with version numbers, the ID that identifies a particular version of a file&#8230; how basic is that?  CVS has it&#8217;s own dot notation.  SVN and Team Server keep a global number that gets incremented when any file is checked in.  This difference in interpretation leads to fundamental differences in how these systems implement labeling and branching.</p>
<p>How could these common concepts be interpreted so differently? It means that in order to move from one version control system to another, you not only have to learn the new commands, but you must understand that system&#8217;s interpretation of what they mean.  Labeling and branching in CVS and SVN are very different, even though the basic concept is the same.  It would be nice to see some a standardization of the implementation of these concepts between version control systems.</p>
<p><strong>Standardized commands</strong></p>
<p>Imagine a world where databases each had their own proprietary language that was completely unrecognized by any other database.  Alright, maybe that&#8217;s not so far off from reality, but beyond PL/SQL, T-Sql and others, there&#8217;s ANSI SQL, which is the common language of all relational databases.  It <em>theoretically</em> (note the italics) allowed developers or DBAs to write SQL that could be understood by any database that supported ANSI SQL.  It&#8217;s the idea of polymorphism at work outside the code, creating a common interface to the functionality, yet allowing each database engine implement that functionality as they wanted.</p>
<p>Version control would be such a happier place if there was a common command language for it, that each version control system was required to implement. On a ground floor level, it would make the simple day-to-day operations consistent.  Update, commit, compare and revert would all be standard.  Once you learned how to use one version control system, you knew how to use ten version control systems.  Is this so hard?</p>
<p><strong>Import/export standardized formats<br />
</strong></p>
<p>A huge point of pain in version control is having to switch from one system to another.  It sounds crazy&#8230; who would switch version control systems at the same company?  However, it&#8217;s happened to me three times in my career.  Companies and departments merge, where both sides used different version control systems.  Sometimes your needs require a version control system with more functionality.  There are lots of reasons for switching systems.</p>
<p>Unfortunately, each time I&#8217;ve had to switch version control systems, it&#8217;s resulted in a complete loss of history. Therefore, there needs to be a standardized import/export format.  Many applications make use of XML as a way to import and export their data to share with other applications.  RSS is probably one of the best examples of this.  Version XML would allow you to export your version history for all files in the repository.  That history, as well as the files or deltas, could then be archived in tar or zip format into a single file.  The corresponding import functionality would be able to read this standard format and structure, and would be able to import that version history. This would completely remove the pain of having to switch from one version control system to another.</p>
<p><strong>Version Query Language<br />
</strong></p>
<p>Basic file check in and check out is the core of any version control system.  However, aside from being able to diff two specific versions of a file there is very little cross version analysis in most systems, despite the fact that the source control repository inherently contains this information. Going back to the SQL analogy used before, a version control repository <em><strong>is a database</strong></em> and users should be able to query it.</p>
<p>I would love to see a standard version query language and table structure that allowed you to run any query you wanted through the version control system&#8217;s engine.  You might be able to write queries like the following (pseudo-queries only):</p>
<p>Who wrote the code at a specific location in a source code file?<br />
<font size="-1"><strong>select author where file = &#8220;x&#8221; and line = y</strong><br />
where x is the file and y is the file line number.</font></p>
<p>Across all files, which version&#8217;s check in comments contain a specific string pattern?<br />
<font size="-1"><strong>select revision_number, file where comment like &#8220;x&#8221;</strong><br />
where x is the check in comment to look for.</font></p>
<p>What check ins has a particular person made in the last 10 days?<br />
<font size="-1"><strong>select file, revision_number where author = &#8220;x&#8221; and checkin_date &gt;= y</strong><br />
where x is the user and y is the date 10 days ago.</font></p>
<p>Which check ins had the biggest effect on a particular file?<br />
<font size="-1"><strong>select top 5 revision_number where </strong></font><font size="-1"><strong>file = &#8220;x&#8221; order by lines_changed desc</strong></font><font size="-1"><br />
where x is the file.</font></p>
<p>We took a stab at that in our <a href="http://www.slickedit.com/content/view/488">Tools for Visual Studio</a> product with the <strong>Find Version</strong> feature.  It allows you to find the versions of one or more files that match specific criteria, such as the ones above.  It does so with a GUI interface, not a query language like I proposed, though.  The most difficult part about this feature was finding a way to do this across several different version control systems, yet maintaining a consistent interface.</p>
<p>In an industry like software development, where most people understand the concept of one interface and many implementations, it&#8217;s amazing to me that this hasn&#8217;t caught on yet in the area of version control.  Maybe some day that will happen, and moving to a new version control system won&#8217;t waste time that could otherwise be used writing code.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F09%2Fcan-we-standardize-version-control%2F';
  addthis_title  = 'Can+we+standardize+version+control%3F';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/09/can-we-standardize-version-control/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Better way to find Eclipse command Ids, and more&#8230;</title>
		<link>http://blog.slickedit.com/2008/08/better-way-to-find-eclipse-command-ids-and-more/</link>
		<comments>http://blog.slickedit.com/2008/08/better-way-to-find-eclipse-command-ids-and-more/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 13:26:45 +0000</pubDate>
		<dc:creator>Ryan</dc:creator>
				<category><![CDATA[Code Editors]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[SlickEdit Products]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=243</guid>
		<description><![CDATA[Core 3.4.0 introduced the Slick-C function _eclipse_execute_command which allows you to execute Eclipse commands from the SlickEdit environment.  The documentation for this function shows you how you can search the Plug-in Registry to find Eclipse command names and ids, but there is a much better way documented in the following blog post:  http://evans-stuff.blogspot.com/2007/10/it-seems-that-im-not-only-one-still.html . 
Unfortunately I [...]]]></description>
			<content:encoded><![CDATA[<p>Core 3.4.0 introduced the Slick-C function <strong>_eclipse_execute_command</strong> which allows you to execute Eclipse commands from the SlickEdit environment.  The documentation for this function shows you how you can search the Plug-in Registry to find Eclipse command names and ids, but there is a much better way documented in the following blog post:  <a target="_blank" href="http://evans-stuff.blogspot.com/2007/10/it-seems-that-im-not-only-one-still.html">http://evans-stuff.blogspot.com/2007/10/it-seems-that-im-not-only-one-still.html</a> . </p>
<p>Unfortunately I discovered this technique after we finished the documentation and shipped the plug-in, but hopefully me pointing it out here may help some users. </p>
<p>Also, don&#8217;t forget the &#8220;Activate Editor&#8221; command in Eclipse (F12 by default).  If you are using <strong>_eclipse_execute_command</strong> to jump into different Eclipse Views and search around mouse-less, hitting F12 will jump you back into the last active editor.</p>
<p><strong>&lt;update&gt;</strong> </p>
<p>Check out this thread of the SlickEdit Forums for adding a generic Eclipse Pass-through Command: <a href="http://community.slickedit.com/index.php?topic=3549.0">http://community.slickedit.com/index.php?topic=3549.0</a></p>
<p><strong>From the post:</strong><br />
If you are evaluating 3.4.0 for your company, you can make this happen easily.  One of the best features in Core 3.4.0 is the introduction of _eclipse_execute_command, which is discussed in the user guide/readme, and also a little more in my post here: <a href="http://community.slickedit.com/index.php?topic=3816.0">http://community.slickedit.com/index.php?topic=3816.0</a> .  This is the idea that Rob suggests in this thread.</p>
<p>I&#8217;ll take this opportunity to give a brief tutorial on how to integrate that &#8220;Activate Task&#8221; shortcut into the SlickEdit environment.</p>
<p>First you need to know the command id of what you are trying to execute.  I used the method described <a href="http://evans-stuff.blogspot.com/2007/10/it-seems-that-im-not-only-one-still.html">http://evans-stuff.blogspot.com/2007/10/it-seems-that-im-not-only-one-still.html</a> , in which you create a Simple Cheat Sheet and use the Command Browse button (see first screenshot).</p>
<p><img src="http://www.slickedit.com/images/stories/blog/task1.png" /></p>
<p>Then I just used the search field to find the command (see second screenshot).</p>
<p><a href="http://www.slickedit.com/images/stories/blog/task2.png"><img src="http://www.slickedit.com/images/stories/blog/task2.png" /></a></p>
<p>Now that I had the command/parameter info, I opened up the Slick-C macro file where I write my custom commands (ryan.e), and added functions for Activate Task and Deactivate Task using _eclipse_execute_command (see third screenshot).  Remember to load your macro file with F12 after writing the functions.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/task3.png"><img src="http://www.slickedit.com/images/stories/blog/task3.png" /></a></p>
<p>Then I used the SlickEdit Keybindings dialog to bind eclipse_activate_task to Ctrl + F9 (see fourth screenshot), and voila.  Hitting Ctrl + F9 in a SlickEdit editor will launch the Mylyn Activate Task dialog.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/task4.png"><img src="http://www.slickedit.com/images/stories/blog/task4.png" /></a></p>
<p>It may seem like a lot of steps, but it&#8217;s really not.  This whole process took me less than 10 minutes including the time I took to capture/crop/annotate the screenshots.  You can use this method to execute almost any Eclipse command from any plug-in from the SlickEdit environment.</p>
<p>- Ryan</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F08%2Fbetter-way-to-find-eclipse-command-ids-and-more%2F';
  addthis_title  = 'Better+way+to+find+Eclipse+command+Ids%2C+and+more%26%238230%3B';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/08/better-way-to-find-eclipse-command-ids-and-more/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Let&#8217;s Do a Code Review With SlickEdit Tools (Part 2)</title>
		<link>http://blog.slickedit.com/2008/07/lets-do-a-code-review-with-slickedit-tools-part-2/</link>
		<comments>http://blog.slickedit.com/2008/07/lets-do-a-code-review-with-slickedit-tools-part-2/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 14:56:10 +0000</pubDate>
		<dc:creator>Scott Hackett</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SlickEdit Products]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=241</guid>
		<description><![CDATA[This article continues Part 1 of the series, where we began the code review process by demonstrating some ways to find the best candidate files to review. We then introduced some techniques to identify what code a specific developer had written, using some of the features in the Versioning Toolbox. The next task is to [...]]]></description>
			<content:encoded><![CDATA[<p>This article continues <a href="http://blog.slickedit.com/?p=237">Part 1 of the series</a>, where we began the code review process by demonstrating some ways to find the best candidate files to review. We then introduced some techniques to identify what code a specific developer had written, using some of the features in the Versioning Toolbox. The next task is to actually comment on the code. This is always best done in an electronic format, in a way that can be pulled together with other developers&#8217; comments during the code review meeting.</p>
<p><strong>Using Code Annotations to Write Review Comments</strong><br />
The Code Annotations feature in the Editing Toolbox is extremely useful for writing code review comments because it lets you attach comments to specific locations in the code without altering the code itself. You can bring up the Code Annotations tool window by clicking <em>SlickEdit &gt; Show Code Annotations</em>.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/codeannotationstoolwindow.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/codeannotationstoolwindow_small.jpg" /><br />
[Click for full size image]</a></p>
<p>The first step when writing code review comments is to create an annotation file to store all of your code review comments. You can then send this file to the code review organizer when you&#8217;re done. You can use the <strong>Annotation File Manager</strong> to create a file called &#8220;<em>Code Review &#8211; Bob</em>&#8221; (or whatever your name may be).</p>
<p><img src="http://www.slickedit.com/images/stories/blog/code_review/codeannotationsfilemanager.jpg" /></p>
<p><strong>Writing Comments About the Code</strong><br />
After applying the <a href="http://www.slickedit.com/images/stories/blog/code_review/defaultuserscheme3.jpg">&#8220;Scott&#8217;s code&#8221; visualization scheme</a> that we made in the first article, we can navigate through the sections of code that Scott has written. On line 497 of <em>PackageBaseWhidbey.cs</em>, we see that he&#8217;s doing a GUID comparison using a literal string. This goes against coding standards, so we&#8217;ll log a comment that the string literal needs to be defined as a constant. Put the cursor on that line and click the <strong>New Annotation</strong> button on the Code Annotations toolbar. This will bring up the <strong>New Annotation</strong> dialog.</p>
<p><img src="http://www.slickedit.com/images/stories/blog/code_review/newannotation.jpg" /></p>
<p>We&#8217;ll create a review comment, which is one of the standard annotation types. We&#8217;ll also select the &#8220;Global : Code Review &#8211; Bob&#8221; scope, or category, which will put the annotation into the code review file we created earlier. After filling out the fields and clicking OK, a purple highlighted marker is placed on the line of the new comment.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/annotatedline1.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/annotatedline1_small.jpg" /><br />
[Click for full size image]</a></p>
<p>Once you create an annotation, it gets an entry in the annotation list. You can select that entry to see a summary of the annotation, or you can double click on it to jump directly to the code it is assigned to. This makes it easy to get to the code that you&#8217;ve commented on.</p>
<p>We also found a bug on line 431 of <em>FileUtility.cs</em>, so a bug annotation can be logged for that. This new annotation has a red highlight to indicate that it&#8217;s a bug type.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/annotatedline2.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/annotatedline2_small.jpg" /><br />
[Click for full size image]</a></p>
<p>It&#8217;s helpful to only show annotations that you have created for the code review, without the clutter of others in the list. You can filter out all non-code review annotations by using the <strong>Annotation Filter Configuration</strong> dialog, available on the code annotations toolbar. Select <strong>Filter by Scope</strong> and select the &#8220;Global : Code Review &#8211; Bob&#8221; item. Now, only your code review annotations will be visible in the list.</p>
<p><img src="http://www.slickedit.com/images/stories/blog/code_review/annotationfilter.jpg" /></p>
<p><strong>Wrapping Up Your Review</strong><br />
Once all of your code review comments have been completed, they will all be contained in the file &#8220;<em>Code Review &#8211; Bob.sca</em>&#8220;, which we created at the beginning of the article (code annotation files have an extension of .sca by default). That file can then be sent to the code review organizer.</p>
<p><img src="http://www.slickedit.com/images/stories/blog/code_review/annotationfileattachment.jpg" /></p>
<p>All of the received code annotation files can then be imported by the organizer during the code review meeting, where they can be discussed. Reviewing code this way maintains a tight link between the code review comments and the actual source code, and is far better than trying to manage the process with pen and paper, or a set of text documents.</p>
<p>You can also create a report of the annotations to print before the meeting, or to send to other developers. To do this, click the <strong>View annotation Detail</strong> toolbar button. The <strong>Code Annotation Details</strong> dialog will be shown and each annotation in the list will be shown in the report. A small red document icon will appear by each annotation that may be clicked to navigate to that annotation in the source code. The report can be exported to HTML or printed.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/annotationreport.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/annotationreport_small.jpg" /><br />
[Click for full size image]</a></p>
<p>The next step will be the actual code review meeting, which will be the focus of part 3 of this series. Once the code annotation files are pulled together from all of the reviewers, those comments can be discussed and updated. After the code review meeting, they can be exported to a single code annotation file and emailed back to the group. The developer being reviewed then has a clear set of action items as a result of the meeting.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F07%2Flets-do-a-code-review-with-slickedit-tools-part-2%2F';
  addthis_title  = 'Let%26%238217%3Bs+Do+a+Code+Review+With+SlickEdit+Tools+%28Part+2%29';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/07/lets-do-a-code-review-with-slickedit-tools-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Let&#8217;s Do a Code Review With SlickEdit Tools (Part 1)</title>
		<link>http://blog.slickedit.com/2008/06/lets-do-a-code-review-with-slickedit-tools-part-1/</link>
		<comments>http://blog.slickedit.com/2008/06/lets-do-a-code-review-with-slickedit-tools-part-1/#comments</comments>
		<pubDate>Wed, 25 Jun 2008 15:11:34 +0000</pubDate>
		<dc:creator>Scott Hackett</dc:creator>
				<category><![CDATA[Code Editors]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SlickEdit Products]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=237</guid>
		<description><![CDATA[As a developer, I look for tools that help me get things done quicker, and make tasks easier. This series of articles shows you how to take a handful of the features in SlickEdit Tools for Microsoft® Visual Studio® and use them to effectively put together and perform a code review.
I can&#8217;t say that I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>As a developer, I look for tools that help me get things done quicker, and make tasks easier. This series of articles shows you how to take a handful of the features in <a href="http://www.slickedit.com/content/view/408/244?utm_source=seblogtoolstut&amp;utm_medium=blog&amp;utm_campaign=seblogtoolstut">SlickEdit Tools</a> for Microsoft® Visual Studio® and use them to effectively put together and perform a code review.</p>
<p>I can&#8217;t say that I&#8217;ve met too many developers that eagerly looked forward to reviewing code. Most developers understand the importance of code reviews, but many have experienced the pain of poorly run code reviews. Although SlickEdit Tools does not have a &#8220;code review&#8221; feature, it provides several features that can be used together to make a code review run smoothly. A well done code review process can be the difference between developer loathing and developer buy-in.</p>
<p>Because code reviews are such a big topic, this article will focus on some of the steps that lead up to a code review. Code reviews typically focus on the work of a single developer, so we&#8217;ll start there. We are going to be code reviewing the developer with ID <em>SLICKEDIT\shackett</em> (or <strong>Scott</strong>) in source control, and we&#8217;ll be reviewing his work since March 3, 2008, which is the date of our last (fictional) release.</p>
<p><strong>Finding the Best Files to Review</strong><br />
Our first challenge involves finding the set of files that Scott has worked on since March 3, 2008. We&#8217;ll use the <strong>Find Version</strong> feature of the SlickEdit Tools Versioning Toolbox as our starting point.</p>
<p><img src="http://www.slickedit.com/images/stories/blog/code_review/findversion.jpg" /></p>
<p>Find Version allows you to query versions of the source code files in your solution. The code review organizer can use this feature to find an ideal set of files to review. Simply click <em>SlickEdit &gt; Find Version</em> to bring up the Find Version tool window. For this example, we&#8217;ll find versions with the following criteria:</p>
<ul>
<li><strong>Since date:</strong> Finds all versions checked in since a particular date, such as the last release.</li>
<li><strong>Developer name:</strong> Finds all versions checked in by one or more specific developers.</li>
</ul>
<p>These two criteria are used to find all versions checked in by Scott during the latest development cycle (March 3, 2008 &#8211; present).</p>
<p>No development team has the resources to code review every file in that list, so it&#8217;s important to find the best candidate files to review. Therefore, the next task is to look through the results and find a sampling of files that represent the most important or complex code. You might also include some files that have a high number of check-ins by that developer, which indicates high rate of change, or churn. These are the ideal candidate files to be reviewed. Email the names of those files to all developers who will be participating in the code review.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/findversionresults.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/findversionresults_small.jpg" /><br />
[Click here for the full size image]</a></p>
<p>In this example, <em>PackageBaseWhidbey.cs</em> has had several changes and is a very important file, so we&#8217;ll include that in our code review process.</p>
<p><strong>Loading the Files to Review</strong><br />
When a developer is ready to prepare their review comments, they should close all other files and open the files in the list sent by the code review organizer. This can be done quickly using the <strong>Load Files </strong>feature in the Editing Toolbox, which allows you to quickly filter the list of files in your solution and open the ones you&#8217;re looking for. Click <em>SlickEdit &gt; Load Files</em> to use this feature.</p>
<p><img src="http://www.slickedit.com/images/stories/blog/code_review/loadfiles.jpg" /></p>
<p>By typing &#8220;<em>basew</em>&#8221; in the filter, we narrow down the files in the list to only those that include that text in their file name. We&#8217;ll select <em>PackageBaseWhidbey.cs</em> and open it.</p>
<p><strong>Isolating a Developer&#8217;s Work</strong><br />
One of the most difficult things to do when reviewing the code of another developer is actually identifying the work that that developer did, especially if it was done as part of a team. Once you have <em>PackageBaseWhidbey.cs</em> open, we&#8217;ll use the <strong>Version Visualizer</strong> feature of the Versioning Toolbox to see which parts Scott has worked on. Click <em>SlickEdit &gt; Version Visualizer</em> to show this tool window. Next, select &#8220;Default User Scheme&#8221; in the drop down at the top of that tool window.</p>
<p><img src="http://www.slickedit.com/images/stories/blog/code_review/versionvisualizer.jpg" /></p>
<p>The versions of the file will be processed and the tool window will list the names of all developers who have contributed to the current state of the file. The editor also becomes colorized into segments of lines that identify who wrote each line of the file.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/defaultuserscheme1.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/defaultuserscheme1_small.jpg" /><br />
[Click here for the full size image]</a></p>
<p>You can find Scott&#8217;s name (<em>SLICKEDIT\shackett</em>) in the tool window list and double click on it to go to the first line of code he contributed. You can then use the next and previous button on the tool window to navigate through the blocks of his work.</p>
<p>To make Scott&#8217;s work stand out more distinctly, select his name (<em>SLICKEDIT\shackett</em>) in the list and click the &#8220;Toggle Selection Visibility&#8221; toolbar button. When toggled on, Scott&#8217;s work will stand out, and all other developer&#8217;s work will be dimmed out. This allows you to quickly see what code is Scott&#8217;s and what code isn&#8217;t. You can click this button again to toggle it back off.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/defaultuserscheme2.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/defaultuserscheme2_small.jpg" /><br />
[Click here for the full size image]</a></p>
<p>Another option is to assign a unique color to Scott. To do this, click the <strong>Configure Visualization Schemes</strong> button on the <strong>Version Visualizer</strong> toolbar. This will bring up the <strong>Scheme Builder</strong> dialog. We&#8217;ll create a new scheme to highlight all areas of code worked on by Scott. Click the <strong>Add new scheme</strong> button and give the scheme a name of &#8220;Scott&#8217;s code&#8221;. We can now add a scheme item for Scott and give it a color of bright red.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/schemebuilder.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/schemebuilder_small.jpg" /><br />
[Click here for the full size image]</a></p>
<p>We can save this visualization scheme and then apply it by selecting it in the <strong>Version Visualizer</strong> drop down. This same scheme can be applied to any file to highlight areas of the code written by Scott.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/defaultuserscheme3.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/defaultuserscheme3_small.jpg" /><br />
[Click here for the full size image]</a></p>
<p>If you find a block of code written by the developer being reviewed that looks questionable, you may want more context about the developer&#8217;s intent, such as the check in comment made when that section of code was checked in. This information is very important for creating meaningful code review comments. The easiest way to do this is to see which version that code was checked in as, and look at the comment associated with that version. To do this, select &#8220;Default Relative Age Scheme&#8221; in the drop down at the top of the <strong>Version Visualizer</strong> tool window.</p>
<p><a href="http://www.slickedit.com/images/stories/blog/code_review/defaultrelativeagecheme.jpg"><img src="http://www.slickedit.com/images/stories/blog/code_review/defaultrelativeagecheme_small.jpg" /><br />
[Click here for the full size image]</a></p>
<p>Again, the versions of the file will be processed, but now the tool window will list the IDs of all versions that have contributed to the current state of the file. The editor also becomes colorized into segments of lines that identify which version last updated each line of the file. The colorizing of each segment corresponds to the age of the version it was checked in with (dark is oldest, light is most recent).</p>
<p>You can find the version associated with the questionable code and take a look at the comments associated with it. You can also use the next and previous button as before to see all of the code in the file that was updated as a result of that check in. For instance, we may have disagreed with the AddMenuCommandHandler function being public. We can see that change was part of version 762. By hovering over that version in the <strong>Version Visualizer</strong> tool window, we get a better understanding of why the function was made public. All of these features assist the team in making judgments about which code to review. They also provide some insight into the motivation the developer being reviewed might have had when checking a set of code in.</p>
<p>Next is the task of actually commenting on the code. This task is always best done in electronic format, in a way that can be pulled together as part of the code review meeting. The <strong>next article</strong> in the series will go through some of the features of SlickEdit Tools that facilitate writing comments about code and tying them directly to the source, without modifying the files.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F06%2Flets-do-a-code-review-with-slickedit-tools-part-1%2F';
  addthis_title  = 'Let%26%238217%3Bs+Do+a+Code+Review+With+SlickEdit+Tools+%28Part+1%29';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/06/lets-do-a-code-review-with-slickedit-tools-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Management&#8221; is a Dirty Word</title>
		<link>http://blog.slickedit.com/2008/06/management-is-a-dirty-word/</link>
		<comments>http://blog.slickedit.com/2008/06/management-is-a-dirty-word/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 14:36:55 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Dev Management]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=233</guid>
		<description><![CDATA[Though it won&#8217;t be flagged as profane in most dictionaries, one word that is often viewed as a dirty word in programming is “management”. Managers are so maligned in engineering that Scott Adams created the “pointy-haired boss” as their representative (http://www.dilbert.com/). It may be true that managers are equally loathed in other fields, but having [...]]]></description>
			<content:encoded><![CDATA[<p>Though it won&#8217;t be flagged as profane in most dictionaries, one word that is often viewed as a dirty word in programming is “management”. Managers are so maligned in engineering that Scott Adams created the “pointy-haired boss” as their representative (http://www.dilbert.com/). It may be true that managers are equally loathed in other fields, but having spent my adult years working in software engineering, this is the only field I feel competent to address. I also have a somewhat unique perspective having been both a developer and a development manager.</p>
<p>I believe that all teams need management. That’s not to say that they all need a manager; some teams do manage themselves. Effective management gets the most out of a team by setting clear goals and minimizing time lost to indecision. A good manager bridges the gap between the business team and the technical team, making sure that both viewpoints are properly considered. A strong development manager can bring a process-centric view to the development team that seeks to improve daily workflows and operations.</p>
<p><strong>So, what’s wrong with “management”? </strong></p>
<p>I think the core reason that software management is so reviled is that it is so rarely done well. In my programming career, I can divide my previous managers into 3 categories:</p>
<ol>
<li><strong>Benevolent, useless, harmless</strong>—this is the category into which fall most of my previous managers. They did a reasonable job of passing along information and managing schedules, but I never really felt they were helping me get my job done. I spent a great deal more time giving them status reports than receiving guidance.</li>
<li><strong>Malevolent, clueless, harmful</strong>—fortunately this category contains only a few of my previous managers. These are the ones who made the job much harder than it needed to be. Sometimes it was done to further their individual goals, like the manager who stuck us with an unreachable milestone so he could get a 30% bonus. Others, it was because they had no idea what we were doing and didn’t have the courage to admit it.</li>
<li><strong>Effective, purposeful, supportive</strong>—by far the smallest population, this is the category we wish all managers fell into but so few actually do. These are the ones who truly help you get your work done by providing the kind of guidance and environment you need to succeed. Tom R., you were the best!</li>
</ol>
<p><strong>How did we get here?</strong></p>
<p>There are so many contributory causes for this problem. The first group, above, is composed of good people who just don’t know what to do. The second group shouldn’t be in charge of themselves, let alone others. I can offer little help to the second group, so let’s focus on the first.</p>
<p>There are two kinds of development managers: those with a strong programming background and those without one (henceforth called “programmers” and “non-programmers”). Even if you have some programming experience, it may not be enough to qualify you as a programmer. You have to have done enough to be considered as a peer on your programming team. I divide managers into these groups because they face different challenges. I’ve worked for managers from both backgrounds and neither is a guarantee of success or failure. My best manager learned his craft managing supermarkets before he went into software development.</p>
<p>To be a successful development manager, you need to know how to manage and enough about software engineering to make appropriate choices. Oddly enough, both groups seem to struggle with the first item. Though the non-programmers tend to have better communication skills than the programmers (if they didn’t, what the heck were they hired for since they’re not programmers?), few of them in my career were skilled managers.</p>
<p><strong>Unique Challenges</strong></p>
<p>The unique challenge faced by the non-programmers is their lack of knowledge about software development. This often hinders their decision-making. A common sign of this is an insistence on keeping to the schedule when a minor slippage could make a huge difference later. When you’ve been around software development long enough, you learn that schedules are fluid. What you do today can make your work tomorrow easier, or harder, depending on the quality of the design and implementation. It takes experience and insight to know when to make these tradeoffs.</p>
<p>Another common problem for the non-programmer manager is not being able to call shenanigans when a developer is snowing you. Even as a programmer, you will never know someone’s code like they will, but you will know from your experience when a developer is likely doing something wrong. My background has helped me to sniff out cases of “design by resume”, where developers chose a particular approach in order to get a trendy new technology on their resume. A non-programmer manager would have a hard time asking the appropriate questions to recognize this.</p>
<p>The programmer managers also face unique challenges. The first is the temptation to code and manage at the same time. I read where others actually recommend this as the desired situation. In my experience, the two activities are incompatible. Effective coding is about immersion, getting into a state of flow, and being very productive. Effective management involves being available to your team to tackle their issues when they arise. Even when I wanted to try to keep coding, I’ve never had a position where the management responsibilities didn’t crowd out any time I allocated for coding. As a manager, my favorite means of being involved with the code is to participate in design discussions and code reviews. This keeps things at a high level and still allows you to contribute your knowledge and experience.</p>
<p>Another problem for the programmer manager is trying to be “one of the guys”. This is manifested as a manager who is hesitant or unable to provide negative feedback. Often, these kinds of managers are promoted from within the team, making this even more of an issue. These managers still view themselves or want to be considered to be a member of the development team rather than its leader.</p>
<p>As a manager, your primary allegiance must be with the business team. Your job is to take their goals and translate them into effective plans to accomplish them. Where you think these goals will lead to problems, you need to point that out. However, if you can’t get them to change the goals, then you need to sign up to them and do your best to accomplish them. Programmer managers sometimes have a difficult time making this change.</p>
<p><strong>Shared Challenges</strong></p>
<p>The most common shared challenge is a lack of knowledge about how to manage. Most of the managers I have worked for had no formal training in management. At best they had a seminar or two. Few ever read any books on management or software development management. Since they, too, have had few truly effective managers, they have no guidance on how to manage. They just don’t know what to do.</p>
<p>An example where this shows up is the weekly status meeting. Most managers have one. They have one because their previous managers had one. In its most typical form, the status meeting lasts for an hour or so while the manager has a conversation with each member of the team, discussing what they are doing. The theory is that having this as a team fosters teamwork and helps everyone to know what everyone else is doing. In reality, the rest of the team already knows or doesn’t care. So this ends up being a large waste of time as the manager has a one-on-one conversation with each team member in front of the rest of the team.</p>
<p>Don’t get me wrong, I’m not saying that status meetings are wrong. But you need to choose to have one because of the benefits the team will get from it, because it is right for this team. Instead, most choose to have one because that’s how they’ve been managed in the past, and it is a visible sign that they are in charge. One of the primary goals of management should be to achieve stated goals with as little interruption in the daily work as possible.</p>
<p><strong>The Solution</strong></p>
<p>What we need to solve this is the same thing we need for all leaders: wise, beneficent individuals with a commitment to goals and compassion for their team. In software development, you need to add in enough knowledge to be mindful of the unique challenges in our field. To erase the pointy-haired boss from our minds or at least remove him as the dominant figure in engineering management, we need enough developers crossing over to become committed managers or enough business managers to gain an appreciation for software development.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F06%2Fmanagement-is-a-dirty-word%2F';
  addthis_title  = '%26%238220%3BManagement%26%238221%3B+is+a+Dirty+Word';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/06/management-is-a-dirty-word/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Great Moments in Idiocy</title>
		<link>http://blog.slickedit.com/2008/04/great-moments-in-idiocy/</link>
		<comments>http://blog.slickedit.com/2008/04/great-moments-in-idiocy/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 14:28:37 +0000</pubDate>
		<dc:creator>Dan H</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=227</guid>
		<description><![CDATA[
April Fool&#8217;s Day was last week.  We had a pretty good April Fool&#8217;s Day post here, but I am not certain how many people got it.  This got me thinking about some of the better office pranks I have seen in my long tenure here at SlickEdit.  Actually, I do not think any of them [...]]]></description>
			<content:encoded><![CDATA[<p><img align="top" width="572" src="http://www.scotthackett.com/slick_edit/welcome_back4.jpg" alt="welcome back" height="428" /></p>
<p><a href="http://en.wikipedia.org/wiki/April_fool%27s_day">April Fool&#8217;s Day</a> was last week.  We had a pretty good <a href="http://blog.slickedit.com/?p=228">April Fool&#8217;s Day post here</a>, but I am not certain how many people got it.  This got me thinking about some of the better office pranks I have seen in my long tenure here at SlickEdit.  Actually, I do not think any of them happened on April Fool&#8217;s day.  But then its always April Fool&#8217;s Day here&#8230;</p>
<ul>
<li><strong><em>Fun with peanuts</em></strong> &#8211; We&#8217;ve all seen the emailed pictures of this sort of thing.  A cubicle &#8220;door&#8221; is closed off with cardboard, and the cubicle is filled with packing peanuts.  There weren&#8217;t enough peanuts to completely fill the area, but I felt this performance was special for a couple of reasons:
<ul>
<li>This an open area with multiple cubicles, so rear walls (whose sole purpose was to hold in the peanuts) had to be constructed.</li>
<li>The Enter key was removed from the keyboard and dropped into the peanuts.  This part, was just plain mean.  A Starbucks gift card was also dropped in to soften the blow.</li>
</ul>
</li>
<li><strong><em>Fun with Shrink wrap</em></strong> &#8211; An office classic.  Various times multiple items on a co-worker&#8217;s desk have been shrink wrapped.  There are a few fun variations:
<ul>
<li>Shrink wrap the telephone, and call the prankee as they are unwrapping the items on their desk.</li>
<li>When a member of the support staff left for some time to get married, <a href="http://www.scotthackett.com/slick_edit/IMG_1773.jpg"><em>everything </em>accessible on his desk was shrink wrapped</a>.  Since we had the occasional office cookout that day, foil was available and the shrink <a href="http://www.scotthackett.com/slick_edit/IMG_1817.jpg">wrapped items were then wrapped in foil</a>.  Finally, the <a href="http://www.scotthackett.com/slick_edit/IMG_1818.jpg">desk</a> was <a href="http://www.scotthackett.com/slick_edit/IMG_1819.jpg">wrapped </a>in <a href="http://www.scotthackett.com/slick_edit/IMG_1821.jpg">foil</a>.  The look on the face when first foil was removed to reveal shrink wrap: <a href="http://youtube.com/watch?v=ZOU8GIRUd_g">priceless</a>.
<ul>
<li>We have not figured out how to shrink wrap an LCD display.</li>
</ul>
</li>
</ul>
</li>
<li><strong><em>Rickrolling</em></strong> &#8211; <a href="http://en.wikipedia.org/wiki/Rickrolling#.22Rickroll.22_Internet_meme">Rickrolling </a>was all the rage around the office a while back.  This is where a link in an e-mail appears to be one thing, but is actually a link to a <a href="http://en.wikipedia.org/wiki/Rick_Astley">Rick Astley</a> video.</li>
<li><strong><em>The ol&#8217; Box On the Desk</em></strong> &#8211; I no longer remember who or when, but one time after a vacation somebody came back to find their desk packed into a box.  I always felt this was a little too mean.</li>
<li><strong><em>Moe&#8217;ing a Cube</em></strong> &#8211; One time a coworker returned from a few days off to find his cube covered in wrappers from <a href="http://moes.com/">Moe&#8217;s</a>.  For good measure, a CD player was hidden under his desk playing the &#8220;Welcome to Moe&#8217;s&#8221; sound clip over and over.  I still have the CD.</li>
<li><strong><em>Mac on the Desk</em></strong>- At some point a co-worker had some Mac experience, but was hoping he would not be asked to work on a SlickEdit Mac port.  He returned from vacation to find a <a href="http://en.wikipedia.org/wiki/Macintosh_SE/30">Mac SE30</a>, a <a href="http://en.wikipedia.org/wiki/Mac_OSX">Mac OSX</a> CD, and note &#8220;We need to talk &#8211; &lt;managername&gt;&#8221;.  Obviously, it looked ridiculous.</li>
<li><strong><em>A Call From a User</em></strong>- When a member of the support staff was leaving to take another job, we arranged for a user who had called support a lot to call and claim he had an absolutely ridiculous problem.  The subterfuge lasted until we could be heard laughing around the corner.</li>
</ul>
<p>That is all I have.  Let&#8217;s hear yours.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F04%2Fgreat-moments-in-idiocy%2F';
  addthis_title  = 'Great+Moments+in+Idiocy';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/04/great-moments-in-idiocy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Next Programming Skill You Should Learn</title>
		<link>http://blog.slickedit.com/2008/03/the-next-programming-skill-you-should-learn/</link>
		<comments>http://blog.slickedit.com/2008/03/the-next-programming-skill-you-should-learn/#comments</comments>
		<pubDate>Wed, 19 Mar 2008 15:29:12 +0000</pubDate>
		<dc:creator>Scott Hackett</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=223</guid>
		<description><![CDATA[Change and growth are faster than ever in software these days. There&#8217;s Silverlight, LINQ and WPF from Microsoft. There&#8217;s AJAX, REST and Rails 2.0 in the web development world. Java has JavaFX. There used to be a time when you had to pick one language and run with it because it was just too overwhelming [...]]]></description>
			<content:encoded><![CDATA[<p>Change and growth are faster than ever in software these days. There&#8217;s Silverlight, LINQ and WPF from Microsoft. There&#8217;s AJAX, REST and Rails 2.0 in the web development world. Java has JavaFX. There used to be a time when you had to pick one language and run with it because it was just too overwhelming to master more than one. Now it&#8217;s impossible to keep up with new developments within even a single language. This has many developers scrambling to figure out what to learn next. No one wants to invest countless hours in a losing technology&#8230; you want to learn something that will be useful in the long run. I have just the skill for you, and it doesn&#8217;t matter what language you work with.</p>
<p>Learn to write well. [<a href="http://www.scotthackett.com/slick_edit/cricket.wav">*</a>]</p>
<p>&#8220;But that&#8217;s not a programming skill!&#8221; you&#8217;re probably saying. Or maybe you&#8217;re disappointed because you thought I was going to be talking about the very latest cutting-edge API you can&#8217;t live without. Good writing skill is probably one of the most useful talents you can develop as a software engineer, and ignoring it is one of the biggest mistakes most programmers make.</p>
<p><strong>Working in a cave<br />
</strong></p>
<p>I used to work with a programmer who we jokingly referred to as a &#8220;walking MSDN&#8221;. He knew all the Win32 APIs, he could tell you the int values of const definitions and could enumerate the parameter lists to functions overloaded 30 times over. As a programmer, when given an assignment, he would <a href="http://blog.slickedit.com/?p=207">go into his cave</a>, hammer out a solution and would re-emerge from his cave with something that worked. I mean that in the most serious way&#8230; he would hammer his code into submission until it worked. There was no such thing as elegant code to him; it worked or it didn&#8217;t.</p>
<p>His manager both loved and feared him because he would do everything required on time, but he had no idea what happened in that cave. There was no visibility at all into what he was doing, and his manager had to blindly rely on the fact that he had a history of getting stuff done on time.</p>
<p>Programmers loved and feared him because he was incredibly knowledgeable and could answer any question about how this or that API worked. But whenever someone had to get inside his code, it was a pure mystery. There was no documentation, no models, no code comments&#8230; nothing but the raw code itself. For mister MSDN, this was no problem, because it was all in his head. For everyone else, it was like being lost in a big city with no map.</p>
<p>Was he a good programmer? Most people that worked with him would say yes&#8230; he was technically proficient and met his deadlines. But most of those same people would also say that they had a very difficult time working with him. That element of fear that he generated was a direct result of not being able, or willing, to communicate. He couldn&#8217;t communicate his plans or designs to other programmers. He couldn&#8217;t communicate his status with his managers. He couldn&#8217;t communicate his interfaces with other teams. Eventually when he left, his code left a wake of terror felt by those that had to pick up where he left off.</p>
<p><strong>The lifespan of a tech skill</strong></p>
<p>Technologies come and go. Seven or so years ago, I felt like I was completely on top of my game when it came to programming technology, at least in the Microsoft world. I had a very deep understanding of COM and ATL, thanks to <a href="http://www.amazon.com/ATL-Internals-Addison-Wesley-Object-Technology/dp/0201695898/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1205862823&amp;sr=8-1">Chris Sells, Brent Rector</a> and <a href="http://www.amazon.com/Professional-Atl-Programming-Richard-Grimes/dp/B0000B0T0K/ref=sr_1_3?ie=UTF8&amp;s=books&amp;qid=1205929348&amp;sr=1-3">Richard Grimes</a>, and I coupled that with VB6 on the front end. This was a really potent combination and I thought I&#8217;d be working with that for years and years. But, as with most technical skills, it didn&#8217;t last long&#8230; .Net came along a year later, ATL became outdated and VB6 just disappeared into the sunset. Now that I&#8217;ve mastered C#, I find that I haven&#8217;t even touched the new stuff in .Net 3.5. The point is, no matter what technology you learn, with very few exceptions, it will disappear or be overshadowed by newer technologies (and probably sooner than later).</p>
<p>Writing skills will last you a lifetime, though. You will always benefit from it, regardless of what language or technology your use, or whether you&#8217;re even a programmer or not. Good writing skills are universal and will never be replaced.</p>
<p><strong>The golden rule of documenting software design</strong></p>
<p>Try to document whatever you are working on. It doesn&#8217;t have to be the worlds most perfect UML and you don&#8217;t need an expensive tool to do it. In fact, Wordpad and Paint are sufficient, and don&#8217;t tell me you don&#8217;t have those. <a href="http://blog.slickedit.com/?p=43">Write in a way that best expresses your intent and your thought process in coming to the design decisions you did</a>. I have a golden rule of documenting software design:</p>
<blockquote><p><em><strong>Describe your design to others as you would have others describe their design to you.</strong></em></p></blockquote>
<p>When you spend the time to do this, you&#8217;ll find that many benefits will follow. You&#8217;ll get feedback from others that may have tried to solve a similar problem and have insight you may not have thought of. You&#8217;ll leave a clear trail to follow for those that work on the code after you. Most importantly, you&#8217;ll shed light on your work, which everyone who depends on your work will appreciate. Even if no one else reads what you write, you&#8217;ll still have worked through problems in your head that can only lead to better design in the long run. <em>There is no downside to documenting your designs. </em></p>
<p>If that wasn&#8217;t enough, consider the fact that someday you may be looking for another programming job. You&#8217;ll sit down with other developers and managers in an interview and try to describe how great your technical abilities are. You are now one of the vast sea of programmers trying to get that job. With your resume alone, a company has only your answers during the interview to base their decision on. With your documentation in hand, though, you can show them in full detail the type of work you&#8217;ve done and give them deeper insight into your thought process than they could ever get from interview questions alone. Your documentation serves as a body of work that travels with you, long after you&#8217;ve stopped working on this or that code, and speaks for your experience.</p>
<p>Of course, these skills won&#8217;t write code for you. But think about how much time you&#8217;ve devoted to learning programming based skills. Think about how many books you&#8217;ve purchased and read about programming. It&#8217;s a huge investment in time and money to keep up with. The next time you have some free cycles to sit down and pick up something new, consider skipping the software development section of the bookstore and pick up a book about technical writing. Here are some good books on this subject:</p>
<ul>
<li><a href="http://www.amazon.com/Writing-White-Papers-Capture-Readers/dp/0977716937/ref=tag_dpp_lp_edpp_ttl_in">Writing White Papers: How to Capture Readers and Keep Them Engaged</a></li>
<li><a href="http://www.amazon.com/Developing-Quality-Technical-Information-Information/dp/0131477498/ref=tag_dpp_lp_edpp_ttl_in">Developing Quality Technical Information: A Handbook for Writers and Editors</a></li>
<li><a href="http://www.amazon.com/Documenting-Software-Architectures-Beyond-Engineering/dp/0201703726/ref=sr_1_4?ie=UTF8&amp;s=books&amp;qid=1205864346&amp;sr=1-4">Documenting Software Architectures: Views and Beyond</a></li>
</ul>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F03%2Fthe-next-programming-skill-you-should-learn%2F';
  addthis_title  = 'The+Next+Programming+Skill+You+Should+Learn';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/03/the-next-programming-skill-you-should-learn/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
<enclosure url="http://www.scotthackett.com/slick_edit/cricket.wav" length="46124" type="audio/wav" />
		</item>
		<item>
		<title>Software Schedules and the Parable of the Loaf of Bread</title>
		<link>http://blog.slickedit.com/2008/03/software-schedules-and-the-parable-of-the-loaf-of-bread/</link>
		<comments>http://blog.slickedit.com/2008/03/software-schedules-and-the-parable-of-the-loaf-of-bread/#comments</comments>
		<pubDate>Wed, 05 Mar 2008 15:28:47 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=221</guid>
		<description><![CDATA[As the manager of a development team, software schedules and estimates are frequently on my mind. A couple of my previous blogs covered estimates: The Perfect Estimate and Software Estimates and the Parable of the Cave. 
Today, I want to discuss a common problem that occurs after the estimate is delivered. Often, the estimate is [...]]]></description>
			<content:encoded><![CDATA[<p>As the manager of a development team, software schedules and estimates are frequently on my mind. A couple of my previous blogs covered estimates: <a href="http://blog.slickedit.com/?p=94">The Perfect Estimate</a> and <a href="http://blog.slickedit.com/?p=207">Software Estimates and the Parable of the Cave</a>. </p>
<p>Today, I want to discuss a common problem that occurs after the estimate is delivered. Often, the estimate is considered to be too high and management tells you how long you have to complete the task. Sometimes this is motivated by important business goals. Other times it’s motivated by a manager who wants to look good or has a bonus tied to a delivery date. </p>
<p>Regardless of the reason, when the team is given the new timeframe they have to scramble to meet it. Often, teams cut corners to try to hit what is, otherwise, an impossible deadline. This has happened to me on a couple projects with what I know now as predictable results. To illustrate it, I offer:</p>
<p><strong>The Parable of the Loaf of Bread</strong></p>
<p>   In a land far away lived a king who was terribly fond of bread. He ate bread at every meal and would often request it as a snack. One day the king requested some bread, but he was told by the royal baker that they were out. Apparently, one of the apprentice cooks had used all the remaining bread to make croutons. </p>
<p>   “Off with his head,” yelled the king, not at all pleased that he couldn’t have some bread. “Now, how long will it take you to get me some bread?”</p>
<p>   “Good King,” replied the royal baker, “I can have a nice, hot loaf of bread for you in about 2 and half hours.”</p>
<p>   “Two and half hours!?!  Not good enough! I want bread sooner. Bring some bread in an hour or you will share the fate of your apprentice.”</p>
<p>   The royal baker returned to his kitchen, determined to meet the king’s deadline. But how could he do it? Every good baker knows that it takes 10 minutes to mix the ingredients for the dough, 15 minutes to knead the dough, an hour to let it rise, and then another hour to bake. How could he finish in an hour? </p>
<p>   “There’s nothing I can do to mix the ingredients faster,” he thought. “But maybe I can let it rise for a shorter time. And maybe I can bake it quicker if the oven is hotter.”</p>
<p>   So he set about to make the loaf of bread, cutting corners wherever possible. He placed the bread in the oven after letting it rise only 20 minutes. He thought to himself that that loaf looked small, but hoped it would come out OK. After 30 minutes he removed the loaf from the oven. The outside was too dark from the higher temperature, but it didn’t look burned. Maybe this will be fine. </p>
<p>   The royal baker rushed the hot loaf up to the king without a minute to spare. The king sliced open the bread to find that the crust was way too hard and the inside too dense and not at all cooked. </p>
<p>   Thoroughly displeased, the king looked at the royal baker and asked, “What is this? This is not a decent loaf of bread!”</p>
<p>   The royal baker replied, “Good King, I did my best to bring you a loaf of bread in the time you allotted, but this is the best that could be done.”</p>
<p>   “How long will it take,” inquired the king, “to bring me a decent loaf of bread?”</p>
<p>   The baker thought for a moment, but there is nothing he can do to shorten the amount of time. “I can have a nice loaf of bread for you in about two and a half hours,” he replied.</p>
<p>   “Two and a half hours!?!” yelled the king. “I already gave you an hour. So bring me some bread in an hour and a half or I’ll cut your head off.”</p>
<p>   The baker returned to his kitchen, highly motivated to give the king what he wanted. Try as he might, he could think of no way to bake a perfect loaf in the amount of time given. So, he took the uncooked center from the first loaf and added in a bit more dough. He didn’t have time to let it fully rise and he had to cook it for less time than it should, but it was the only way he could produce a loaf in the allotted time. </p>
<p>   At the end of the hour and a half, the baker returned to the king with the new loaf of bread. Again, it was overly done on the outside. The inside was a mixture of dry, dense dough and underdone dough.</p>
<p>  The king was furious and called the guards to have the baker executed. He had the assistant baker brought before him and asked him how long it would take to bake a nice loaf of bread. The assistant baker, clearly unnerved by the fate of the former head, now headless, baker responded, “Your Majesty, I am aware of your desire for some nice bread. However, there is nothing I can do to speed the process and produce a loaf that is worthy of your Highness.  I can bring you a nice loaf of bread in about two and a half hours, but I could make you some delicious rolls in about half that time.”</p>
<p>   The king mulled it over for a few moments and said, “Very good. Some rolls would be nice.”</p>
<p>The End.</p>
<p>In software development, this cycle is all too common. A deadline looms and we eliminate steps that we know are essential to producing quality code. We throw out unit testing or greatly reduce the number of tests produced. We eliminate design and code reviews so we can spend more time writing code. I’ve even seen projects curtail analysis and design thinking they can adapt as they figure out the fine points later.</p>
<p>The problem with this is that cutting corners produces poor software, often with a high rate of defects or a design that can’t be extended or modified to meet changing requirements. As the code base grows and has more of this low-quality code, every subsequent unit of development takes longer than the ones before it. Rather than providing the basis to speed subsequent development, it slows it down as you are forced to trace problems and limitations in work that was previously “done”.</p>
<p>It’s hard to get non-developers to understand the impact of using poorly written code. But it is as clear and obvious to developers as attempting to use a half-backed loaf of bread to jump-start the creation of a new loaf. So it’s important to push back and try to educate your partners about what they are asking you to do. </p>
<p>Explain the risks involved and why essential steps can’t be skipped. I’m not saying that you should be a purist. Be pragmatic and willing to bend. When your back is against the wall, you should look for ways to perform steps, like unit testing, as quickly and efficiently as possible. You may find that the business need warrants the risk of skipping unit testing on infrequently used or less complex code paths. </p>
<p>Try to get them to reduce the scope of what is planned, just as in the parable when the assistant baker offered rolls instead of a loaf of bread. Cutting features is the surest way to shorten a schedule. Even if you don’t get permission to drop features, work on the code in an iterative and incremental manner. Get the essential functionality finished before adding bells and whistles, even if you’re told you can’t ship without them. When they’re given the option of shipping without them or shipping nothing, you’d be surprised how often they are willing to leave them off.</p>
<p>Hopefully, your project is a team effort and not a monarchy. Just as there are development considerations that they may not understand, there may be business considerations that you don’t understand. Work together to define an acceptable level of risk and then perform your development accordingly. </p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F03%2Fsoftware-schedules-and-the-parable-of-the-loaf-of-bread%2F';
  addthis_title  = 'Software+Schedules+and+the+Parable+of+the+Loaf+of+Bread';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/03/software-schedules-and-the-parable-of-the-loaf-of-bread/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Stick Your Head in the Oven (and other things I&#8217;ve learned)</title>
		<link>http://blog.slickedit.com/2008/02/dont-stick-your-head-in-the-oven-and-other-things-ive-learned/</link>
		<comments>http://blog.slickedit.com/2008/02/dont-stick-your-head-in-the-oven-and-other-things-ive-learned/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 13:41:33 +0000</pubDate>
		<dc:creator>Dan H</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=215</guid>
		<description><![CDATA[You should not stick your head in the oven.  There are a number of reasons:

Gas oven

If the gas is on, but the pilot light is out, you could asphyxiate and die
If the gas is on, and the pilot light is on, the oven will be hot.  You could be badly burned, and breath in heated [...]]]></description>
			<content:encoded><![CDATA[<p>You should not stick your head in the oven.  There are a number of reasons:</p>
<ol>
<li>Gas oven
<ol>
<li>If the gas is on, but the pilot light is out, you could asphyxiate and die</li>
<li>If the gas is on, and the pilot light is on, the oven will be hot.  You could be badly burned, and breath in heated air which will damage your lungs, and you could die</li>
</ol>
</li>
<li>Electric oven
<ol>
<li>If the oven is on, the oven will be hot.  You could be badly burned, and breath in heated air which will damage your lungs, and you could die</li>
</ol>
</li>
<li>In general
<ol>
<li>If you stick your head in an oven that is on you will be badly hurt</li>
<li>Ovens tend to be dirty.  You will get dirty.
<ol>
<li>If you have long hair, it will get dirty and that&#8217;ll be a real mess.
<ol>
<li>If you are a man with long hair right now, you are recognized by pretty much everybody around you as somebody who is stuck in 1987.  I&#8217;m not saying this is a bad thing, just that if you choose to have your hair cut every other political administration, you&#8217;ll stand out in a crowd</li>
</ol>
</li>
</ol>
</li>
</ol>
</li>
</ol>
<p>When you come right down to it, there just isn&#8217;t a really good reason to put your head in an oven.  I know they need to be cleaned from time to time, and you have to reach in to get the back, but really you don&#8217;t have to put your head in, you can just reach your arm out.</p>
<p>I never had to be told not to stick my head in the oven, I managed to figure it out on my own.  I&#8217;m not sure at what age I had this revelation, but I&#8217;m sure it was early (to be fair, my mother may actually have mentioned it at some point, but I&#8217;m confident I would have figured it out).</p>
<p>Here are some other things I learned:</p>
<ol>
<li>Initialize variables
<ol>
<li>When you declare a variable, it takes an extra few seconds to initialize it.  Always do this.  If you don&#8217;t, you will just find yourself going &#8220;I should have initialized that&#8221; when you fix a bug related to it not being initialized later
<ol>
<li>Uninitialized variables are a pain to track down</li>
</ol>
</li>
<li>Static variables in C are guaranteed to be set to 0 at startup.
<ol>
<li>Initialize them anyway.  It makes the code more clear and saves you the let down when you think you found an uninitialzed variable problem before you remember that they will be initialized to 0 at startup.</li>
</ol>
</li>
</ol>
</li>
<li>Check in code
<ol>
<li>While it is really unpopular to check in code that might break a build, and you might be ridiculed by your peers for it, it will be much more uncomfortable to explain that you lost a week of work because your hard drive crashed.</li>
<li>Sometimes you lose stuff.  Code that was not checked in is no exception.  Not in my case at least. </li>
<li>Hard drives crash (see 2.1).</li>
</ol>
</li>
</ol>
<p>Most of these lessons somebody did tell me somewhere along the line.  But I find that a lot of the smaller lessons in life I have to learn the hard way (sometimes more than once).  Of course some of those lessons should be as obvious as not sticking your head in the oven.</p>
<p>I am going to go continue to work on a feature for SlickEdit 2008.  While I am working on it, I will try to remember not to stick my head in the oven.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F02%2Fdont-stick-your-head-in-the-oven-and-other-things-ive-learned%2F';
  addthis_title  = 'Don%26%238217%3Bt+Stick+Your+Head+in+the+Oven+%28and+other+things+I%26%238217%3Bve+learned%29';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/02/dont-stick-your-head-in-the-oven-and-other-things-ive-learned/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Help With MSDN Help</title>
		<link>http://blog.slickedit.com/2008/02/help-with-msdn-help/</link>
		<comments>http://blog.slickedit.com/2008/02/help-with-msdn-help/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 17:21:04 +0000</pubDate>
		<dc:creator>Scott Hackett</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=216</guid>
		<description><![CDATA[F1&#8230; it&#8217;s possibly the most feared key on my keyboard when writing code in Visual Studio. At best, it&#8217;s going to bring up MSDN help, aka dexplore.exe. That means that I&#8217;m in for a very, very long wait. Startup time is 3 minutes on average, and I&#8217;m an Athlon 64 dual core @ 2 GHz [...]]]></description>
			<content:encoded><![CDATA[<p>F1&#8230; it&#8217;s possibly the most feared key on my keyboard when writing code in Visual Studio. At best, it&#8217;s going to bring up MSDN help, aka <strong>dexplore.exe</strong>. That means that I&#8217;m in for a very, very long wait. Startup time is 3 minutes on average, and I&#8217;m an Athlon 64 dual core @ 2 GHz with 1 GB RAM. The worst case scenario is that something has updated MSDN help and it has to reconfigure itself. The last time this happened, I waited aver 15 minutes. This dialog is like the <a href="http://en.wikipedia.org/wiki/Medusa">Medusa</a> of Windows&#8230; just the sight of it turns your computer to stone.</p>
<p><img src="http://www.slickedit.com/images/stories/blog/helpupdate.jpg" /></p>
<p>I could understand if dexplore were processing <a href="http://setiathome.berkeley.edu/">SETI</a> data on startup, crunching <a href="http://www.worldcommunitygrid.org/projects_showcase/viewHpfResearch.do">genome data</a>, or possibly computing sophisticated weather patterns. But let&#8217;s be honest, it&#8217;s a glorified web browser. All of the help it provides can be found <a href="http://msdn2.microsoft.com/">online</a>, and chances are, it&#8217;s more up to date online than it is dexplore.</p>
<p>Apparently, I&#8217;m not the only one that completely hates the help system. AprilR reports in her blog that Microsoft is <a href="http://blogs.msdn.com/aprilr/archive/2008/01/28/help-is-getting-help-the-long-overdue-makeover-for-visual-studio-and-msdn-help.aspx">overhauling MSDN help</a> based on user feedback. That&#8217;s great, but why has it taken so long? The only conclusion I can come to is that Microsoft must simply not use it. If anyone on the Visual Studio development team actually used it, it would have been overhauled a long time ago. It&#8217;s a shame too, because the actual MSDN content is, in general, very good.</p>
<p>Maybe someday we can go back to chm. It just worked and did the same job that MSDN does, just a million times faster. Well, everything except online content, but&#8230; that&#8217;s why I have Firefox installed on my computer (yes, <em><strong>Firefox</strong></em>). I set up my own help launcher macro to spawn a web browser, take the selected text and do a Google search on MSDN and the selected text.</p>
<p>Here&#8217;s the macro:</p>
<p><img src="http://www.slickedit.com/images/stories/blog/macro.jpg" /></p>
<p>Now, if you go into Tools &gt; Options and select Environment / Keyboard, you can bind <strong>Macros.MyMacros.HelpModule.LaunchWebBrowser</strong> to the F1 key (or whatever you like). Now, when you press F1, it will go right to Google and search for &#8220;MSDN [selection]&#8221; where [selection] is any selected text in your active document. It&#8217;s faster than launching dexplore and gets better results, at least for my purposes. The one thing it can&#8217;t do is determine the type context of your selection, but that can be fixed by by adjusting the search query.</p>
<p>Help is one of the most basic needs of every programmer. It&#8217;s an &#8220;I use it every day&#8221; kind of tool. <a href="http://go.microsoft.com/fwlink/?LinkId=102169">Give Microsoft your feedback</a>, because if there&#8217;s one thing that needs help in Visual Studio, it&#8217;s the help.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F02%2Fhelp-with-msdn-help%2F';
  addthis_title  = 'Help+With+MSDN+Help';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/02/help-with-msdn-help/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Right Now, What are You Listening To?</title>
		<link>http://blog.slickedit.com/2008/01/right-now-what-are-you-listening-to/</link>
		<comments>http://blog.slickedit.com/2008/01/right-now-what-are-you-listening-to/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 13:46:12 +0000</pubDate>
		<dc:creator>Dan H</dc:creator>
				<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=182</guid>
		<description><![CDATA[There are two kinds of developers &#8211; those who wear headphones so constantly that they could be some kind of cybernetic implant, and those who I guess are not distracted as easily.  For me the headphones are a constant, except when working at home, but then the stereo is a constant.
I normally start the day with Opie [...]]]></description>
			<content:encoded><![CDATA[<p>There are two kinds of developers &#8211; those who wear headphones so constantly that they could be some kind of cybernetic implant, and those who I guess are not distracted as easily.  For me the headphones are a constant, except when working at home, but then the stereo is a constant.</p>
<p>I normally start the day with Opie and Anthony on <a href="http://xmradio.com/">XM radio</a>.  This is fine first thing in the morning, but when the coffee kicks in and my brain reaches operating temperature, I switch to music.</p>
<p>I have always been a big <a href="http://www.van-halen.com/news.html">Van Halen</a> fan, but I find that the only time I really listen to them anymore is when a need a couple of hours of incredible focus.  I can turn those old albums up to unsafe levels, and usually get some work done.  Occasionally I will do the same thing with <a href="http://metallica.com/">Metallica</a>, but only the early albums.  I&#8217;ve never felt the same about their music since I saw <a href="http://www.imdb.com/title/tt0387412/">Some Kind of Monster</a>.</p>
<p>I also find that times that I get stressed out, I tend to revert to the soundtrack of my early youth.  This involves a lot of Simon and Garfunkel, Jim Croce, John Denver, and Glenn Campbell.  It was the 1970s - the decade that brought us the <a href="http://en.wikipedia.org/wiki/Leisure_suit">leisure suit</a>, <a href="http://en.wikipedia.org/wiki/Lawn_darts">lawn darts</a>, and Ken Olson of Digital Equipment Corporation told us &#8220;<a href="http://www.2spare.com/item_50221.aspx">There is no reason anyone would want a computer in their home</a>&#8221; (To be fair, this far from the most short-sighted quote out there about the future of the computer industry, it was just the first one I found from the 70s).</p>
<blockquote><p>Note 1: If anybody has a picture of a leisure suit, would they please contribute it to the <a href="http://en.wikipedia.org/wiki/Leisure_suit">Wikipedia article on leisure suits</a>.</p>
<p>Note 2: I have no idea when lawn darts were invented.  It seems to me that it would have to be the 1970s.</p></blockquote>
<p>Right now, I am listening to &#8220;<a href="http://theband.hiof.no/lyrics/the_weight.html">The Weight</a>&#8221; by <a href="http://theband.hiof.no/">The Band</a>.  What are you listening to?</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F01%2Fright-now-what-are-you-listening-to%2F';
  addthis_title  = 'Right+Now%2C+What+are+You+Listening+To%3F';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/01/right-now-what-are-you-listening-to/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>QA Deathmatch</title>
		<link>http://blog.slickedit.com/2008/01/qa-deathmatch/</link>
		<comments>http://blog.slickedit.com/2008/01/qa-deathmatch/#comments</comments>
		<pubDate>Wed, 09 Jan 2008 13:50:42 +0000</pubDate>
		<dc:creator>Scott Hackett</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=209</guid>
		<description><![CDATA[I&#8217;ve worked previously at several companies that didn&#8217;t have a QA department available. When the code freeze happened, all of the developers would go into QA mode. We&#8217;d then spend the next few weeks testing the features, and typically each developer would test their own. It was possibly the most feared and hated time of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve worked previously at several companies that didn&#8217;t have a QA department available. When the code freeze happened, all of the developers would go into QA mode. We&#8217;d then spend the next few weeks testing the features, and typically each developer would test their own. It was possibly the most feared and hated time of the year.</p>
<p>If you&#8217;re familiar with <a href="http://www.idsoftware.com/">Quake</a>, or pretty much any other <a href="http://en.wikipedia.org/wiki/First-person_shooter">FPS</a>, then you know about the <a href="http://en.wikipedia.org/wiki/Deathmatch_%28gaming%29">deathmatch</a>. It&#8217;s my single favorite type of game and, in it&#8217;s own way, is really therapeutic when the stress of development, or testing, gets you down. A lot of the other developers I worked with at one point also loved to deathmatch and we used to play during lunch. When testing time came around, we found a way to make it fun&#8230; <strong>QA Deathmatch</strong>.</p>
<p>Here are the rules for QA Deathmatch:</p>
<ol>
<li><strong>Scoring works on a point system:</strong> the points correspond to your company&#8217;s severity levels for bugs. If you find a bug, you score that bug&#8217;s severity level in damage. The person who owns that bug sustains that many points of damage. If your severity level goes in reverse order, then you score ([max severity] &#8211; [bug severity] + 1) per bug. For instance, assume your company has a severity level of 1 for critical bugs, and 5 for cosmetic bugs. If you find a bug with a severity of 2, then you score (5 &#8211; 2 + 1) or 4 points of damage and the bug&#8217;s owner sustains 4 points of damage.</li>
<li><strong>Damage can be recovered:</strong> by fixing a bug that caused the damage. When a bug is fixed, you reduce your damage sustained by the point total for that bug. However, the person who found the bug <em>does not</em> reduce their damage total.</li>
<li><strong>All features are fair game:</strong> there are points to be won everywhere in the code base, don&#8217;t limit yourself. The more you try all of the features, the more chance you have of scoring big.</li>
<li><strong>First to find a bug gets the points:</strong> If you find a bug that&#8217;s already been logged, you score nothing.</li>
</ol>
<p>All players have three running stats:</p>
<ul>
<li><strong>Damage delivered:</strong> The sum of the bug scores <em>found by you</em>.</li>
<li><strong>Damage sustained:</strong> The sum of the scores of the bugs <em>found by other players</em> against your features.</li>
<li><strong>Damage recovered:</strong> The sum of the damage <em>reduced by you</em> by fixing bugs.</li>
</ul>
<p>At the end of each day, the point totals are taken and five medals of honor are awarded:</p>
<ul>
<li><strong>Sniper medal:</strong> The person who delivered the most damage</li>
<li><strong>Stealth </strong><strong>medal</strong><strong>:</strong> The person who sustained the least damage</li>
<li><strong>Tactics </strong><strong>medal</strong><strong>:</strong> The person who had the best delivered:sustained ratio</li>
<li><strong>Medic </strong><strong>medal</strong><strong>:</strong> The person who recovered the most damage</li>
<li><strong>Commander medal:</strong> The person with the greatest overall score as calculated by [delivered - sustained + recovered].</li>
</ul>
<p>The point of all of this is that it makes testing fun. It gives you motivation to find bugs, fix bugs and make your features as solid as you can. It&#8217;s amazing what winning one or two medals at the end of the day can do to make you feel great about going into testing for another day. And if you think winning a medal is motivating, wait until you lose a medal to someone else.</p>
<p>Another great thing that QA deathmatch encourages is getting everyone to test all aspects of the system. Too often, developers only test their features and don&#8217;t go outside that box. However, there are bugs to be found everywhere, and when you are in scoring mode, you&#8217;ll take the time to check out all the new features to see what you can break to score big. It&#8217;s also a great facade for getting competitive about finding bugs. Nobody likes the guy that finds a lot of bugs in their features, and even fewer like to be that guy. It&#8217;s easy to feel bad about finding a lot of bugs. You&#8217;re essentially adding work to other people&#8217;s plates. But in QA deathmatch, you are playing a role and it&#8217;s a great way to detach personal feeling from the process.</p>
<p>There are other variations of the game too:</p>
<ol>
<li><strong>Team play: </strong>Development is split into two or more teams, divided by feature sets. Point totals are not by individual, but by team.</li>
<li><strong>Capture the flag:</strong> Just like team play, but instead of end-of-day totals, points are calculated when bugs are found or fixed. Instead of medals, flags are used that can be stolen by any team at any time. It feels great to find or fix a bug, then be able to steal a flag from another team.</li>
<li><strong>Mercenaries:</strong> Testers that aren&#8217;t involved in fixing bugs are mercenaries. They may not participate on a team or get any of the normal medals. Instead, a special <em>Mercenary award</em> is given to the one who scores the most damage in a day.</li>
</ol>
<p>Again, the whole point is to make testing fun. All you need is a whiteboard, a calculator and some gadgets to be used as medals. Of course, you can always add to the game by printing a bunch of <a href="http://www1.istockphoto.com/file_thumbview_approve/4213435/2/istockphoto_4213435_cartoon_skull_and_crossbones.jpg">these</a> then taping one to a developer&#8217;s cube with the bug number and severity penciled in whenever a bug is found. It can only be removed when the bug is fixed. The possibilities for expansion are endless.</p>
<p>QA is a painful process and some days, when 8+ hours of QA work lay ahead of you, it&#8217;s just hard to get out of bed in the morning. Don&#8217;t let boring work be boring. Not only will you have more fun during the day, but I can guarantee that when you turn QA into a competitive deathmatch, the quality of the final product going out the door will be better than if you are finding and fixing bugs for the sake of quality alone. Happy sniping!</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2008%2F01%2Fqa-deathmatch%2F';
  addthis_title  = 'QA+Deathmatch';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2008/01/qa-deathmatch/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Software Estimates and the Parable of the Cave</title>
		<link>http://blog.slickedit.com/2007/12/software-estimates-and-the-parable-of-the-cave/</link>
		<comments>http://blog.slickedit.com/2007/12/software-estimates-and-the-parable-of-the-cave/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 20:29:13 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Dev Management]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=207</guid>
		<description><![CDATA[As discussed in a previous blog, The Perfect Estimate, providing software estimates is one of the most challenging aspects in the software industry. There are many reasons for this, not the least of which is the challenge of estimating the unknown. Unlike many other construction activities, like erecting a skyscraper or building a ship, software [...]]]></description>
			<content:encoded><![CDATA[<p>As discussed in a previous blog, <a href="http://blog.slickedit.com/?p=94">The Perfect Estimate</a>, providing software estimates is one of the most challenging aspects in the software industry. There are many reasons for this, not the least of which is the challenge of estimating the unknown. Unlike many other construction activities, like erecting a skyscraper or building a ship, software projects often involve new combinations of technologies (at least for those on the project) assembled in unique ways.</p>
<p>The more a task resembles a previously completed task, the easier it is to estimate. Ideally, metrics kept about the previous task will include time spent on various activities and the total time overall. When estimating the new task, you could analyze which activities are likely to change based on completing the previous one and derive an estimate for the new task.</p>
<p>In order to best illustrate the challenges of software estimates, I will use the time-proven technique of the parable.</p>
<p><strong>The Parable of the Cave</strong></p>
<p>Two people stand before a cave. One is the sagely manager of a cave exploring company who’s wisdom is only exceeded by his wit, charm, and humility. Let’s call him, oh, “Scott”. The other is a cave explorer of indeterminate gender who bears no resemblance to any programmers past or present that this author may have worked with and whose size may be big or little. Let’s call him/her “Endian”.</p>
<p>“Endian,” said Scott in a sagely voice that was both commanding and compassionate, “I need you to explore this cave. But before you do, I need to know how long you think it will take, so that I may build a schedule and tell the sales team when the cave will be ready.”</p>
<p>“Great Scott,” replied Endian using the title bestowed upon Scott by his admiring employees, “how can I give you an answer when surely you know I have never been in this cave before? The cave may be vast, with deep chasms. It may contain a labyrinth of underwater passages. It may contain fearsome creatures that must first be vanquished. How can I say how long it will take to explore?”<br />
Scott pondered Endian’s words and after a thorough analysis that might have taken days for others but was completed in but a moment for him, he replied, “Surely this is not the first cave you explored. Are there no other caves in this district? Use your knowledge of those caves to form an estimate.”</p>
<p>Endian heard these words and still his doubt prevailed. “Your words are truly wise,’’ said Endian, “but even within a district the caves may vary, one from another. Surely, an estimate based on the size of another cave cannot be deemed accurate.”</p>
<p>“You have spoken truly, good Endian,” replied Scott in a fatherly, supporting tone that lacked any trace of being patronizing as certain cynical readers may think. “Here, take from me this torch and this assortment of cheeses that you may explore the cave briefly. Return ere the morrow and report what you have learned.”</p>
<p>The parable continues like this for pages, as parables are known to do. Let’s see, Endian enters the cave…something about a wretched beast of surpassing foulness…he continues on…hmm, that’s what the assortment of cheeses were for. Ah! Here we go.</p>
<p>Endian returns to Scott, his t-shirt ripped and his jeans covered in mud. Being always concerned with the well-being of his employees, Scott offers Endian a cool drink, then asks, “Endian, what news of the cave? Have you an estimate that I can use for my schedule? What shall I tell the sales team?”</p>
<p>Endian considers all that he has seen and builds a decomposition containing the many tasks necessary to explore the cave based on his earlier reconnoitering. He factors in variables for risk and unknowns, and then he responds, “Two weeks.”</p>
<p><strong>Applying this Wisdom</strong></p>
<p>To truly appreciate the punch line, you do need to check out <a href="http://blog.slickedit.com/?p=94">The Perfect Estimate</a>.</p>
<p>The point I’m trying to illustrate is that estimating software development is like estimating the time needed to explore a cave you’ve never been in. You don’t really know until you get in there. Still, there are techniques that can help.</p>
<p>First, draw on your experience. Even though technologies may be very different, few automation problems are empirically new. They bear resemblance to other things we’ve done in the past.</p>
<p>Expect the unexpected! Make sure you factor time in for the unknowns. If your schedule only contains the things you can think of, then it’s certainly going to fall short when the unexpected arises. There will always be things you don’t know to put into the schedule.</p>
<p>Provide estimates that are ranges rather than just a single duration. If a task can take 2 to 4 weeks, provide it in that manner. If your project planning software cannot accomodate date ranges, enter the task as 2 weeks and then put in a secondary task for another 2 weeks to account for this. I like to name these tasks, &#8220;risk factors&#8221;. So, if I have a task called, &#8220;Integration Testing&#8221;, I would add another called, &#8220;Integration Testing, Risk Factor&#8221;. This way, I can specifically see how much time has been set aside for this variability, and I can see what happens to the schedule if I increase or decrease that amount of time.</p>
<p>Make your estimates as fine-grained as possible. An estimate for a task that only needs a few hours is far more likely to be accurate than an estimate for one that will need a couple weeks. By making your estimates as detailed as possible you not only improve accuracy but the work necessary to create a detailed estimate will often turn up tasks you might otherwise overlook.</p>
<p>Even if your manager only wants an overall estimate, you should do a detailed decomposition to make sure you build the best estimate possible. This decomposition will also serve as a guide during your work, both as a checklist to make sure you haven&#8217;t forgotten something and as a status check to see if you are on time. This can help you timebox activities, applying the available time to a task. Projects can run over due to time spent waffling on design decisions. Timeboxing tells you when it&#8217;s time to make a decision and move on.</p>
<p>Build your decompositions with tasks that are either complete or incomplete. When tracking progress, don’t fall into the trap of recording activities as some percentage complete. A task is either finished or not finished. Showing partial completion leads to a false sense of security.</p>
<p>Use incremental and iterative processes. As in the parable, sometimes it’s useful to make a quick, preliminary exploration in order to build a more comprehensive estimate. Continue to refine your estimates and the overall plan. The closer you get to the end, the more accurate your schedule should be.</p>
<p>Work on the riskiest part of the system first. Too often projects run over when someone discovers a large problem in the final stages of the work. Assess the risk of each portion of the work and tackle first those parts that are most likely to exceed their estimates or induce changes in the rest of the system.</p>
<p>Lastly, it is absolutely critical that an environment of trust exists between the development team and the rest of the company. Your job should be to deliver the best estimate you can with appropriate risk factors identified. Too often estimates are inflated to make sure that we can hit them. Equally often, due dates are set artificially early to allow for overages. Both of these strategies prevent the company from building an effective plan for this project and developing appropriate contingencies. Worse, these constraints sometimes lead to poor choices and compromises during development that add further risk.</p>
<p> </p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F12%2Fsoftware-estimates-and-the-parable-of-the-cave%2F';
  addthis_title  = 'Software+Estimates+and+the+Parable+of+the+Cave';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/12/software-estimates-and-the-parable-of-the-cave/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>East Bound and Down&#8230; (some joke about &#8220;codin&#8221;)</title>
		<link>http://blog.slickedit.com/2007/10/east-bound-and-down-some-joke-about-codin/</link>
		<comments>http://blog.slickedit.com/2007/10/east-bound-and-down-some-joke-about-codin/#comments</comments>
		<pubDate>Wed, 31 Oct 2007 13:17:28 +0000</pubDate>
		<dc:creator>Dan H</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SlickEdit Products]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=114</guid>
		<description><![CDATA[In this industry, we have to be very careful which features we select to add to our products each release.  Even with the growing amount of time and scrutiny dedicated to choosing these features, we occasionally miss the mark.  As an illustration of this point, I am going to talk about Coors, and Smokey and [...]]]></description>
			<content:encoded><![CDATA[<p><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffsetup1.JPG" title="diffsetup1"></a><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput1.JPG" title="diffoutput1"></a><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffsetup1.JPG" title="diffsetup1"></a><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput1.JPG" title="diffoutput1"></a><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput21.JPG" title="diffoutput2"></a>In this industry, we have to be very careful which features we select to add to our products each release.  Even with the growing amount of time and scrutiny dedicated to choosing these features, we occasionally miss the mark.  As an illustration of this point, I am going to talk about Coors, and Smokey and the Bandit.  Try to stick with me until the end where I will try to tie all this together.  At the very least, you will understand why I am not a teacher.</p>
<p><a href="http://en.wikipedia.org/wiki/Coors_Brewing_Company">The Coors Brewing Company of of Golden, Colorado, USA</a>, had a fairly profound impact on the thirty-somethings in the world like myself.  You see, we have been led to believe for thirty years or so that it was once illegal to transport Coors beer East of Texas.  As far as I can tell, this was never true (although it was <a href="http://en.wikipedia.org/wiki/Coors_Brewing_Company#History">not nationally available until sometime in the 1990s</a>).  Nonetheless it was the plot of the hit 1977 movie Smokey and the Bandit.  And when I say &#8220;hit 1977 movie&#8221;, it was the second highest grossing movie of that year.  Star Wars was number one.  It is not Scorcese or [fill in name of artsy director you like here], but it was a big deal.</p>
<p>I don&#8217;t want to get off on a big tangent here, but a small one is necessary, stick with me.  For anybody who did not get basic cable over the last thirty years, the basic plot is as follows:</p>
<ul>
<li>It is illegal to ship Coors beer East of Texas</li>
<li>Burt Reynolds and Jerry Reed are paid a large some of money to get 400 cases Coors beer from Texarkana, Texas to Atlanta, Georgia in twenty-eight hours</li>
<li>Burt Reynolds distracts cops from the speeding eighteen wheeler carrying the 400 cases of beer by performing really cool stunts in a 1977 Trans Am
<ul>
<li>In order to keep a low profile, the eighteen wheeler is painted with a mural of a masked bandit robbing a stagecoach.</li>
</ul>
</li>
<li>Jerry Reed sings his hit song, &#8220;East Bound and Down&#8221;</li>
<li>Hillarity insues</li>
</ul>
<p>Sounds ridiculous right?  Well, it does lack the realism of &#8220;Die Hard&#8221;, but it is actually not a bad movie provided that:</p>
<ol>
<li>You are a guy<a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput21.JPG" title="diffoutput2"></a></li>
<li>When you watch a movie you want to be entertained and don&#8217;t question things too much.</li>
</ol>
<p>But the point here is that history was changed:</p>
<ul>
<li>The mystique of Coors beer was further boosted to those who could not get it East of Texas.  Here I need to emphasize that people thought it was really illegal to take Coors beer East of Texas.</li>
<li>The Trans-Am became as cool as the (<a href="http://en.wikipedia.org/wiki/Evel_Knievel#Retirement.28s.29">then recently jailed</a>) <a href="http://en.wikipedia.org/wiki/Evel_Knievel">Evel Knievel</a> with suburban pre-teens across America.</li>
<li>Jerry Reed had a hit single.</li>
</ul>
<p>As much as I love old Trans-Ams, and that song, what I want to focus on is the first item in that list: People believed that it was illegal to take Coors beer East of Texas.  This is one of the standout facts people in the United States know about Coors beer.  What they do not know is this: in 1959 Coors was the first beverage in America to be packaged in a <a href="http://en.wikipedia.org/wiki/Aluminum_can">two-piece aluminum can</a>.  These cans are a part of common life today.  There are two on my desk right this minute (diet soda, not beer).  They are so common place people my age really cannot picture a world without them.  A world where I am told you had to use a can opener (one of the pointy triangluar ones, not the rotating ones with a blade) simply to drink a beverage.  I imagine the people at The Coors Brewing Company of of Golden, Colorado are proud of having introduce this convenient, and recyclable, can.  But far more people remember that it was illegal to ship Coors beer East of Texas (and when I say &#8220;far more people&#8221;, I  mean &#8220;me&#8221;).</p>
<p>What could this <em>possibly </em>have to do with software development?  It can be difficult to figure out what people will latch onto.  In my tenure at SlickEdit, I have seen a lot of sleep lost over features that did not make quite the splash we hoped they would.  Thankfully none of these turned out to be as big a blunder as the <a href="http://en.wikipedia.org/wiki/Edsel">Edsel</a>.  I will share the one that personally hit me the hardest though:</p>
<ol>
<li>Launch SlickEdit&#8217;s DIFFzilla® setup dialog (Tools&gt;File Difference)</li>
<li>Fill in &#8220;Path 1&#8243; and &#8220;Path 2&#8243; with any two files that SlickEdit tags</li>
<li>Click the &#8220;Symbols&#8221; radio button at the top left</li>
<p style="text-align: center"><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffsetup1.JPG" title="diffsetup1"><img width="200" src="http://blog.slickedit.com/wp-content/uploads/2007/10/diffsetup1.thumbnail.JPG" alt="diffsetup1" height="115" class="imageframe imgalignleft" /></a></p>
<p><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffsetup1.JPG" title="diffsetup1"></a></p>
<li>Clicking OK will yield output that actually show changes on a <em>symbol</em> level, including modified functions and added/deleted functions.</li>
<p><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput1.JPG" title="diffoutput1"></a><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput1.JPG" title="diffoutput1"></a></p>
<p style="text-align: center"><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput1.JPG" title="diffoutput1"><img width="200" src="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput1.thumbnail.JPG" alt="diffoutput1" height="125" class="imageframe imgalignleft" /></a></p>
<p><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput1.JPG" title="diffoutput1"></a></p>
<li>Selecting an item from this list and clicking &#8220;Diff&#8221; will actually compare just those two functions in the DIFFzilla output dialog.</li>
<p><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput21.JPG" title="diffoutput2"></a><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput21.JPG" title="diffoutput2"></a></p>
<p style="text-align: center"><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput21.JPG" title="diffoutput2"><img width="200" src="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput21.thumbnail.JPG" alt="diffoutput2" height="125" class="imageframe imgalignleft" /></a></p>
<p><a rel="lightbox[pics114]" href="http://blog.slickedit.com/wp-content/uploads/2007/10/diffoutput21.JPG" title="diffoutput2"></a></ol>
<p>This can be convenient for a number of reasons.  Sometimes a function moved, and the file itself has changed so much diffing two whole files just confuses matters.  This feature will shine in those cases.</p>
<p>I thought this would be a hit.  Everybody here thought it was a neat idea, and I worked feverishly to sneak this into the 8.0 release.  It was not a hit.  In fact, I am not certain that a user has ever actually used this feature.  It is generally good for a &#8220;wow&#8221; or two at a trade show though.</p>
<p>The moral of the story?  Be careful when you choose to add features.  The <a href="http://en.wikipedia.org/wiki/Aluminum_can">two-piece aluminum can</a> may not look nearly as flashy as a 1977 Trans-Am, but people will still be using it 50 years later.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F10%2Feast-bound-and-down-some-joke-about-codin%2F';
  addthis_title  = 'East+Bound+and+Down%26%238230%3B+%28some+joke+about+%26%238220%3Bcodin%26%238221%3B%29';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/10/east-bound-and-down-some-joke-about-codin/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Comparing Python to Perl and Ruby</title>
		<link>http://blog.slickedit.com/2007/09/comparing-python-to-perl-and-ruby/</link>
		<comments>http://blog.slickedit.com/2007/09/comparing-python-to-perl-and-ruby/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 16:23:21 +0000</pubDate>
		<dc:creator>Clark Maurer</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=162</guid>
		<description><![CDATA[Comparing Python to Perl and Ruby
Anyone who knows me well, knows that I am really into programming languages. Like editors, a programming language is a tool which is supposed to make your programming task easier.
Unlike the typical programmer, I have experience designing and implementing languages. Slick-C, the macro language in SlickEdit, is the third fairly [...]]]></description>
			<content:encoded><![CDATA[<h1>Comparing Python to Perl and Ruby</h1>
<p>Anyone who knows me well, knows that I am really into programming languages. Like editors, a programming language is a tool which is supposed to make your programming task easier.</p>
<p>Unlike the typical programmer, I have experience designing and implementing languages. Slick-C, the macro language in SlickEdit, is the third fairly major programming language I&#8217;ve been involved with. My experience and passion for programming languages gives me quite a bit more insight into performance and elegance.</p>
<p>I started learning Python because SlickEdit needed better support for the language. Unlike Ruby, I never heard a lot of hoopla about Python. The programming world has many, many scripting languages, most of them poorly designed. I figured that Python was probably just another poorly designed language with little or no technical merits.</p>
<p>I&#8217;ve been puzzled by the popularity of Perl since it has so many flaws. By the way, just because I dislike some elements of Perl doesn&#8217;t mean I will direct SlickEdit not to provide great support for it. SlickEdit language enhancements are based on popularity, and currently Perl is more popular than Python. However, that doesn&#8217;t mean I won&#8217;t rank on it a bit. Heck, I rank on C/C++ and it&#8217;s the language I use most (beware of sharp knife). To date, we have spent WAY more time on Perl and Ruby support than Python. This will always be the case, because it is WAY easier to implement Python support.</p>
<p>I have done my best to make these comparisons unbiased. The only code that I have written for these languages is sample code to better understand these languages. I do have good experience in parsing these languages either for color coding or tagging symbols for SlickEdit. My opinions are based on what I think make a state-of-the-art language. My next article &#8220;A Deeper Look at Python&#8221;, will talk more about Python and what things make a language state-of-the-art.</p>
<p>This comparison of Python, Perl, and Ruby is from a grammar perspective and does not cover the run-times of these languages. There are often cases where you end up choosing a language due to its run-time features. I&#8217;m not going to cover run-time features here. A detailed chart of reasons to choose one or the other which includes run-times would be very useful though.</p>
<h2>Python Versus Perl</h2>
<p>Python beats Perl by a mile. In a nut shell, Python and Perl have similar language features but Python is way easier to learn and use than Perl. Here are some specific examples:</p>
<p>Perl</p>
<div class="codecolorer-container perl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">sub</span> func <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;"># You've got to be kidding parameter passing.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Perl 6 intends to fix this.</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$x</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$arrayRef</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">=</span><span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;"># Crud, this modifies the callers $i.</span><br />
&nbsp; &nbsp; <span style="color: #339933;">++</span><span style="color: #0000ff;">$x</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$arrayRef</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;">#YUCK! Modify the callers array.</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># By default, all variables are global in Perl. This</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># is potentially more dangerous.</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$newvar</span><span style="color: #339933;">=</span> <span style="color: #ff0000;">'abc'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># this is a global variable</span><br />
&nbsp; &nbsp; <span style="color: #000066;">print</span> <span style="color: #0000ff;">$x</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">return</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #0000ff;">$i</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;"># Choose the right variable prefix for a list</span><br />
<span style="color: #0000ff;">@array</span><span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #666666; font-style: italic;">#Passing an array by reference is ugly</span><br />
<span style="color: #0000ff;">$x</span><span style="color: #339933;">=</span>func<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #0000ff;">\@array</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$newvar</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;i=&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$i</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># i is 2</span><br />
<span style="color: #666666; font-style: italic;"># You're kidding, I need to change the prefix</span><br />
<span style="color: #0000ff;">$array</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #000066;">print</span> <span style="color: #0000ff;">$array</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot; &quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$array</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span> &nbsp;<span style="color: #666666; font-style: italic;"># prints 4 0</span></div></td></tr></tbody></table></div>
<p>Python</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> func<span style="color: black;">&#40;</span>x,<span style="color: #dc143c;">array</span>,z=<span style="color: #483d8b;">'Cool! Default value'</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; i=<span style="color: #ff4500;">2</span> &nbsp; <span style="color: #808080; font-style: italic;"># This declares a new local variable</span><br />
&nbsp; &nbsp; x+=<span style="color: #ff4500;">1</span> &nbsp;<span style="color: #808080; font-style: italic;"># Hmm...No ++ operator in Python.</span><br />
&nbsp; &nbsp; <span style="color: #dc143c;">array</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>=<span style="color: #ff4500;">4</span><span style="color: #66cc66;">;</span> &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#Modify the callers list</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> x,z<br />
&nbsp; &nbsp; newvar=<span style="color: #483d8b;">'abc'</span><span style="color: #66cc66;">;</span> &nbsp;<span style="color: #808080; font-style: italic;"># This declares a new local variable</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span> <br />
i=<span style="color: #ff4500;">1</span><br />
<span style="color: #dc143c;">array</span>= <span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span>, <span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span> &nbsp;<span style="color: #808080; font-style: italic;"># Python calls this a list</span><br />
<span style="color: #808080; font-style: italic;"># Passing a list by reference works like</span><br />
<span style="color: #808080; font-style: italic;"># the C# List&lt;T&gt; generic.</span><br />
x=func<span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>,<span style="color: #dc143c;">array</span><span style="color: black;">&#41;</span><br />
<span style="color: #808080; font-style: italic;">#print newvar; &nbsp;This won't compile</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;i=&quot;</span>,i &nbsp;<span style="color: #808080; font-style: italic;"># i is 1</span><br />
<span style="color: #dc143c;">array</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>=<span style="color: #ff4500;">0</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">array</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>,<span style="color: #dc143c;">array</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">;</span> &nbsp;<span style="color: #808080; font-style: italic;"># prints 4 0</span></div></td></tr></tbody></table></div>
<p>Python is a big improvement over Perl. I would provide more reasons why Python is much better but I&#8217;d like to keep this article short. I will say that Perl has a very large and arguably cryptic grammar. Perl is hard for others to quickly read and understand. I find Perl hard to write as well. Because Perl has a lot of syntax which is so different from other programming languages, you quickly forget it and must read the language documentation again.</p>
<h2>Python Versus Ruby</h2>
<p>Comparing Python and Ruby is not as simple as showing some small snippets of code as I did above. For me, Python is clearly a better language than Ruby but I can understand why some people might like Ruby better. Ruby took the &#8220;kitchen sink&#8221; approach. It has language syntax for pretty much all the features of Perl, Python, and then some. Ruby embraces many of Perl&#8217;s complex features, which may make Ruby seem more familiar to the Perl fanatic than Python. There are loads of &#8220;shorthands&#8221; and optional syntax. To the naive person, lots of features give the false impression that the language is better or somehow more powerful.</p>
<p>While more can mean better, it definitely doesn&#8217;t in Ruby&#8217;s case. Due to the very large grammar, Ruby is way more difficult to learn than Python. The comment on the Ruby web site about Ruby being easy to learn is definitely not true. Reading Ruby code written by someone else is a problem too since others will use constructs you are not familiar with or don&#8217;t like. The ambiguities in the language make it much harder for editing tools to provide smart editing features. I&#8217;m not willing to give up smart editing features for shorthands which save a few characters. If you are using a dumb editor, then you might see this differently.</p>
<p>In order to keep this article short, I will not show all the constructs in Ruby which make it a large ambiguous grammar. So this may look like I&#8217;m nit picking.</p>
<h2>Poor Ruby Syntax Choices</h2>
<p>Here are some poor Ruby syntax choices:</p>
<p>Ruby</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># Due to these poor choices...</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> i<span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#006666;">5</span> <span style="color:#9966CC; font-weight:bold;">then</span> <br />
&nbsp; &nbsp;<span style="color:#CC0066; font-weight:bold;">puts</span> i <br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">while</span> i<span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#006666;">10</span> <span style="color:#9966CC; font-weight:bold;">then</span> <br />
&nbsp; &nbsp;i<span style="color:#006600; font-weight:bold;">+</span>=<span style="color:#006666;">1</span> <br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#008000; font-style:italic;"># This syntax for the shorthand forms is hard</span><br />
<span style="color:#008000; font-style:italic;"># to read for most of us.</span><br />
<span style="color:#CC0066; font-weight:bold;">puts</span> i <span style="color:#9966CC; font-weight:bold;">if</span> i<span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#006666;">5</span><br />
i<span style="color:#006600; font-weight:bold;">+</span>=<span style="color:#006666;">1</span> <span style="color:#9966CC; font-weight:bold;">while</span> i<span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#006666;">10</span><br />
<span style="color:#008000; font-style:italic;"># The syntax below bloats the language.</span><br />
<span style="color:#CC0066; font-weight:bold;">puts</span> i <span style="color:#9966CC; font-weight:bold;">unless</span> i<span style="color:#006600; font-weight:bold;">&gt;</span>=<span style="color:#006666;">5</span> &nbsp;<span style="color:#008000; font-style:italic;"># Same as &quot;puts i if i&lt;5&quot;</span></div></td></tr></tbody></table></div>
<p>Python</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># These long hands are easily compressed</span><br />
<span style="color: #ff7700;font-weight:bold;">if</span> i<span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">5</span>: <br />
&nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">print</span> i<br />
<span style="color: #ff7700;font-weight:bold;">while</span> i<span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">10</span>:<br />
&nbsp; &nbsp;i+=<span style="color: #ff4500;">1</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> i<span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">5</span>: <span style="color: #ff7700;font-weight:bold;">print</span> i<br />
<span style="color: #ff7700;font-weight:bold;">while</span> i<span style="color: #66cc66;">&lt;</span><span style="color: #ff4500;">10</span>: i+=<span style="color: #ff4500;">1</span></div></td></tr></tbody></table></div>
<p>Ruby should have chosen a syntax which allows for a more conventional single line statement like one of the following:</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># C-like syntax</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> expr <span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp;put s; &nbsp;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> expr <span style="color:#006600; font-weight:bold;">&#41;</span> put s; <br />
<br />
<span style="color:#008000; font-style:italic;"># Pascal-like syntax</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> expr <span style="color:#9966CC; font-weight:bold;">then</span> <span style="color:#9966CC; font-weight:bold;">begin</span> &nbsp; &nbsp;<span style="color:#008000; font-style:italic;"># could use 'do' instead of 'begin'</span><br />
&nbsp; &nbsp;put s; &nbsp;<br />
<span style="color:#9966CC; font-weight:bold;">end</span>;<br />
<span style="color:#9966CC; font-weight:bold;">if</span> expr <span style="color:#9966CC; font-weight:bold;">then</span> put s; <br />
<br />
<span style="color:#008000; font-style:italic;"># Python syntax is best</span><br />
<span style="color:#9966CC; font-weight:bold;">if</span> expr: <br />
&nbsp; &nbsp;put s<br />
<span style="color:#9966CC; font-weight:bold;">if</span> expr: put s</div></td></tr></tbody></table></div>
<h2>Function Pointers or Function Objects</h2>
<p>Ruby really messed up with function pointers (or function objects):</p>
<p>Ruby</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># What planet did this come from?</span><br />
<span style="color:#9966CC; font-weight:bold;">def</span> func<span style="color:#006600; font-weight:bold;">&#40;</span>list<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> list<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">yield</span> i<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
func<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'cat'</span>,<span style="color:#996600;">'dog'</span>,<span style="color:#996600;">'horse'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>animal<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> animal<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>Python</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># This is from earth</span><br />
<span style="color: #ff7700;font-weight:bold;">def</span> doSomething<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> i<br />
&nbsp; &nbsp;<br />
<span style="color: #ff7700;font-weight:bold;">def</span> func<span style="color: black;">&#40;</span><span style="color: #008000;">list</span>,function<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">list</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp;function<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Python does not yet have multi-line anonymous </span><br />
<span style="color: #808080; font-style: italic;"># functions. The lambda functions in Python are weak.</span><br />
func<span style="color: black;">&#40;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'cat'</span>,<span style="color: #483d8b;">'dog'</span>,<span style="color: #483d8b;">'horse'</span><span style="color: black;">&#93;</span>,doSomething<span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Ruby</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># This is better</span><br />
<span style="color:#9966CC; font-weight:bold;">def</span> func2<span style="color:#006600; font-weight:bold;">&#40;</span>list,function<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">for</span> i <span style="color:#9966CC; font-weight:bold;">in</span> list<br />
&nbsp; &nbsp; &nbsp; &nbsp;function.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>i<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
func2<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'cat'</span>,<span style="color:#996600;">'dog'</span>,<span style="color:#996600;">'horse'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># proc(animal) is a better choice</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># delegate(animal) is like C#</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">proc</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>animal<span style="color:#006600; font-weight:bold;">|</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> animal<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp;<span style="color:#006600; font-weight:bold;">&#41;</span></div></td></tr></tbody></table></div>
<p>The first Ruby example uses syntax which none of us should ever have to learn. To make matters worse, the keyword &#8220;yield&#8221; is used which means something totally different in C# and Python. I haven&#8217;t yet found a way to pass a predefined function as an argument to a Ruby function. Ruby does support passing method pointers using the &#8220;method&#8221; feature (ex &#8220;variable.method(:methodName)&#8221;), but again Python provides a much simpler syntax. To pass a method pointer in Python you just specify &#8220;variable.methodName&#8221; like you would in C#.</p>
<p>Ruby&#8217;s grammar is riddled with multiple ways of doing things. Adding to the confusion, it often unnecessarily chooses syntax different from popular languages we are familiar with.  As a result, Ruby is much more difficult to learn, read, and write.</p>
<p>Not everything is better in Python. For example, Ruby&#8217;s class/member syntax is better than Python. For me, this doesn&#8217;t help Ruby nearly enough to make it a better language.</p>
<h2>Summary</h2>
<p>Both Ruby and Perl have large ambiguous grammars (Perl&#8217;s grammar is worse). They often disambiguate syntax based on context. For example, the slash symbol (/) can mean divide or perform a search depending on the context. In the search case, the slash is used to delimit the string. This is an unnecessary complexity since this is just another way to call a function with string parameters.</p>
<p>There will never be a case where having a very large and ambiguous grammar makes a language better. This is one of the flaws in C++. I&#8217;m an excellent C++ programmer and I&#8217;ve had to stare at some C++ statements for way too long. Note that Java and C# have very small unambiguous grammars with only a few shorthands. Modern languages have so many features that they must keep the grammar small in order to reduce the learning curve. I guarantee that the best state-of-the-art languages of the future will do the same. For this reason alone, Python is clearly better than Ruby or Perl. Keep in mind that I have not compared the run-times of these languages and there are often cases where you end up choosing a language due to its run-time features.</p>
<p>There are other ways that scripting languages can speed the programming process without creating a large grammar with excessive shorthands. For example, unqualifying names with import/using statements and choosing short name space names for standard run-times (Python does both of these). Also, if the grammar is small and unambiguous, editing tools like SlickEdit can provide more assistance.</p>
<p>My next article &#8220;A Deeper Look at Python&#8221;, will talk more about Python and what things make a language state-of-the-art.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F09%2Fcomparing-python-to-perl-and-ruby%2F';
  addthis_title  = 'Comparing+Python+to+Perl+and+Ruby';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/09/comparing-python-to-perl-and-ruby/feed/</wfw:commentRss>
		<slash:comments>52</slash:comments>
		</item>
		<item>
		<title>Creating a PHP 5 Extension with Visual C++ 2005</title>
		<link>http://blog.slickedit.com/2007/09/creating-a-php-5-extension-with-visual-c-2005/</link>
		<comments>http://blog.slickedit.com/2007/09/creating-a-php-5-extension-with-visual-c-2005/#comments</comments>
		<pubDate>Tue, 18 Sep 2007 13:08:21 +0000</pubDate>
		<dc:creator>Matthew E</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=128</guid>
		<description><![CDATA[This article describes the steps to create a custom PHP extension DLL for the Windows platform. The Zend API documentation that comes with PHP 5 on Windows (see php_manual_en.chm) does a good job explaining how to write extension methods, parse method parameters, and return values. But there is not currently a good step-by-step tutorial on [...]]]></description>
			<content:encoded><![CDATA[<p>This article describes the steps to create a custom PHP extension DLL for the Windows platform. The Zend API documentation that comes with PHP 5 on Windows (see php_manual_en.chm) does a good job explaining how to write extension methods, parse method parameters, and return values. But there is not currently a good step-by-step tutorial on how to get your first extension project up and running on Windows. The aim of this article is to fill that gap.</p>
<h4>Prerequisites</h4>
<ul>
<li><strong>Visual Studio 2005</strong><br />
You can alternately use the free Visual C++ Express Edition or the VC++ 8 compiler in the Windows SDK v6.0 if you&#8217;re a makefile master. Visual Studio 2003 (VC++ 7) will probably work just fine, but some of the project configuration steps will be different than what is explained here</li>
<li><strong>A web server</strong><br />
For this article I used <a href="http://www.sambar.com/download.htm">Sambar Server</a> 7.0. Any HTTP server that can run the PHP 5.x ISAPI extension (php5isapi.dll) will do</li>
<li><strong>PHP 5 binaries</strong>, installed and configured for your server<br />
I used PHP 5.2.4. Using the windows installer package (.msi file) makes configuration easier</li>
<li><strong>PHP 5 source code</strong><br />
DONT PANIC! You do not need to build PHP from source, just get the source that matches your binary version. You will need an extraction utility like <a href="http://winrar-download-now.com">WinRAR</a> or <a href="http://zipgenius.it">ZipGenius</a> that can handle .tar archives.</li>
</ul>
<h4>Conventions</h4>
<p><em>Italics</em> denote file paths and names. <em>C:\Server\PHP\dev</em><br />
Screenshot icons <img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" height="16" /> provide links to images showing how dialogs are configured.<br />
Document icons <img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/textdoc.png" /> provide links to sample code files.</p>
<h2>Configuring the Environment</h2>
<p>I will not discuss installing and running the HTTP web server. If you do not already have IIS available on your machine, I recommend the <a href="http://www.sambar.com/download.htm">Sambar Server</a>.</p>
<p>If you do not already have PHP 5 installed, download it from <a href="http://www.php.net/downloads.php">php.net</a>. If you download and run the MSI installer package, it will configure your web server.</p>
<p>After you&#8217;ve got PHP 5 installed and configured for your server, download and extract the complete PHP 5 source code, also from <a href="http://www.php.net/downloads.php">php.net</a>. <strong>Caution:</strong> Do NOT extract the source archive over top of your existing binary installation. This article&#8217;s example setup includes the PHP 5 binaries installed to <em>C:\Server\PHP5</em>, and the source code extracted to <em>C:\Server\PHP5Src</em>.</p>
<h2>Creating the Project</h2>
<p>In Visual Studio 2005, create a new Visual C++ Win32 project using the project template.<a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/newproj.png" title="Creating the Project"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" alt="Creating the Project" height="16" /></a> For this example, I named the project CustomExt. When the Win32 Application Wizard appears, click <strong>Application Settings</strong> (on the left) and select DLL as the application type. <a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/dllproj.png" title="Change to DLL project"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" alt="Change to DLL project" height="16" /></a> Click Finish to create the project.</p>
<p>I recommend following along step-by-step, but you can also download the <a href="http://blog.slickedit.com/wp-content/uploads/2007/09/customext.zip" title="Full sample code">complete project source</a> (zipped). You&#8217;ll still need to follow the instructions for changing the directories to match your system.</p>
<h4>Change Default C++ Options</h4>
<p>Bring up the Project Properties dialog, and make sure the Debug configuration is active. Under <strong>Configuration Properties &gt; General</strong>, change the Character Set to &#8220;Use Multi-Byte Character Set&#8221;. <a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/mbcs.png" title="Set character set"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" height="16" /></a></p>
<p>Then under <strong>Configuration Properties &gt; C/C++ &gt; Code Generation</strong>, change the following options: <a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/opts1.png" title="C++ &gt; Code Generation"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" height="16" /></a></p>
<ul>
<li>Enable String Pooling to &#8220;Yes (/GF)&#8221;</li>
<li>Enable Minimal Rebuild to &#8220;No&#8221;</li>
<li>Basic Runtime Checks to &#8220;Default&#8221;</li>
<li>Runtime Library to &#8220;Multi-threaded Debug (/MTd)&#8221;</li>
</ul>
<p>Under <strong>Configuration Properties &gt; C/C++ &gt; General</strong>, change the following:</p>
<ul>
<li>Debug Information Format to &#8220;Program Database (/Zi)&#8221;</li>
<li>Detect 64-bit Portability Issues to &#8220;No&#8221;</li>
</ul>
<p>Be sure to click <strong>Apply</strong> to save the settings.</p>
<h4>Set the INCLUDE Paths</h4>
<p>Still on the Project Properties dialog unders <strong>Configuration Properties &gt; C/C++ &gt; General</strong>, in the Additional Include Directories, add the following paths, replacing <em>C:\Server\PHP5Src</em> with the location on your machine where you extracted the source code.<a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/includes.png" title="Include paths"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" height="16" /></a></p>
<pre>C:/Server/PHP5Src/main
C:/Server/PHP5Src/Zend
C:/Server/PHP5Src/TSRM
C:/Server/PHP5Src/regex
C:/Server/PHP5Src</pre>
<p>Again, be sure to click Apply to save the settings as you go along.</p>
<h4>Set the Preprocessor Definitions</h4>
<p>On the Project Properties dialog, under <strong>Configuration Properties &gt; C/C++ &gt; Preprocessor</strong>, add the following definitions:<a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/preproc.png" title="Preprocessor options"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" /></a></p>
<pre>ZEND_DEBUG=0    

ZTS=1    

ZEND_WIN32    

PHP_WIN32</pre>
<p><strong>Note:</strong> Do not be tempted to change ZEND_DEBUG to 1, even for this Debug build, as this will prevent your extension from being loaded into the pre-built PHP binaries installed on your system.</p>
<h4>Set the Linker Options</h4>
<p>On the Project Properties dialog, under <strong>Configuration Properties &gt; Linker &gt; General</strong> add the path to the <em>C:\Server\PHP\dev</em> directory to the Additional Library Directories. This is the directory underneath your installed <strong>PHP binaries</strong> (not the extracted source). This directory should contain <em>php5ts.lib</em>.<a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/linkdir.png" title="Linker directory"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" /></a></p>
<p>Under <strong>Configuration Properties &gt; Linker &gt; Input</strong>, add <em>php5ts.lib</em> to the Additional Dependecies.<a rel="lightbox[pics128]" href="http://blog.slickedit.com/wp-content/uploads/2007/09/libdep.png" title="Add the .lib"><img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/cam16.png" /></a></p>
<p>By convention, php extensions start with php_, so under <strong>Configuration Properties &gt; Linker &gt; General</strong>, for the Output File option, I changed the output name to <em>php_custom_ext.dll</em>. This is entirely optional.</p>
<h4>The Extension Code</h4>
<p>Replace the contents of stdafx.h with the following, or <a href="http://blog.slickedit.com/wp-content/uploads/2007/09/stdafx_h.txt" title="stdafx.h">download it <img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/textdoc.png" /></a>:</p>
<pre>#pragma once
/* PHP Extension headers */
/* include zend win32 config first */
#include "zend_config.w32.h"
/* include standard header */
#include "php.h"</pre>
<p>Replace the contents of <em>ProjectName</em>.cpp (in this example CustomExt.cpp) with the following (<a href="http://blog.slickedit.com/wp-content/uploads/2007/09/customext_cpp.txt" title="CustomExt.cpp">or download it <img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/textdoc.png" /></a>):</p>
<pre>#include "stdafx.h"/* declaration of functions to be exported */
ZEND_FUNCTION(DoubleUp);
/* compiled function list so Zend knows what's in this module */
zend_function_entry CustomExtModule_functions[] = {
   ZEND_FE(DoubleUp, NULL)
    {NULL, NULL, NULL}
};    

/* compiled module information */
zend_module_entry CustomExtModule_module_entry = {
    STANDARD_MODULE_HEADER,
    "CustomExt Module",
    CustomExtModule_functions,
    NULL, NULL, NULL, NULL, NULL,
    NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
};    

/* implement standard "stub" routine to introduce ourselves to Zend */
ZEND_GET_MODULE(CustomExtModule)
/* DoubleUp function */
/* This method takes 1 parameter, a long value, returns
   the value multiplied by 2 */
ZEND_FUNCTION(DoubleUp){
    long theValue = 0;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                              "l", &amp;theValue) == FAILURE){
        RETURN_STRING("Bad parameters!", true);
    }
    theValue *= 2;
    RETURN_LONG(theValue);
}</pre>
<p>You should now be able to build the project without any errors. Be careful when renaming <strong>CustomExtModule</strong> or <strong>DoubleUp</strong>, and you must replace every instance in the file, or the Zend macros will yield nearly indecipherable compiler errors.</p>
<h2>Enable the extension</h2>
<p>The first step is to locate the <em>\ext</em> directory beneath your <strong>PHP 5 binaries</strong> (not the directory where you extracted the PHP source code). On my sample system this is <em>C:\Server\PHP\ext</em>. Copy the DLL that you just built to this directory. If you are going to attach a debugger to your extension, you will also want to copy the .pdb files.</p>
<p>The second step is to configure PHP to load your extension DLL. You do this by modifying PHP.ini, adding a</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">extension=php_ext_name.dll</div></td></tr></tbody></table></div>
<p>line to the Dynamic Extensions section, like the following.</p>
<pre>;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
[CustomExt]
extension=php_custom_ext.dll</pre>
<h4>Verify that the extension can be loaded</h4>
<p>Once you&#8217;ve edited and saved php.ini, you may need to restart the HTTP server in order to pick up the new module. After the server is restarted, browse to the phpinfo.php web page. If you do not already have a phpinfo.php page, create one using the following text, and save it to one of your virtual directories:</p>
<pre>&lt;?php
phpinfo();
?&gt;</pre>
<p>Now browse to http://localhost/<em>virtualpath</em>/phpinfo.php, and look for the <strong>Additional Modules</strong> section. Your new extension should now be seen in the listing. If your extension is not listed, you may need to resave php.ini and restart the server. Also, make sure that the php.ini file that your server is using is the same ini file that you just edited. On most servers, php.ini is located in the PHP 5 installation directory, but your server may be different. To make certain, look at the information at the top of the page for the <strong>Loaded Configuration File</strong> entry, which shows the full path to the ini file PHP is currently using.</p>
<h4>Write a test page</h4>
<p>Copy the following code to testext.php (<a href="http://blog.slickedit.com/wp-content/uploads/2007/09/testext_php.txt" title="testext.php">or download it <img width="16" src="http://blog.slickedit.com/wp-content/uploads/2007/09/textdoc.png" /></a>) , save it under one of your web server&#8217;s virtual directories.</p>
<pre>&lt;?php
$value = 14;
$result = DoubleUp($value);
print "Calling DoubleUp($value) returned $result";
?&gt;</pre>
<p>You can now browse to http://localhost/<em>virtualpath</em>/testext.php.</p>
<h2>Debugging the extension</h2>
<p>In order to debug the extension you need to attach the debugger to the running instance of the web server process. For IIS, this is w3wp.exe. For the Sambar server, this is sambar70\bin\server.exe. On the Project Properties dialog, under <strong>Configuration Properties &gt; Debugging </strong>, set the following values:</p>
<ul>
<li>Command to the full path to the server executable</li>
<li>Attach to &#8220;Yes&#8221;</li>
<li>Debugger Type to &#8220;Native Only&#8221;</li>
</ul>
<p>Stop you web server and make certain that you have copied the latest version of the extension DLL and the .pdb files to the <em>\ext</em> directory, then restart the web server. Set a breakpoint in the DoubleUp method and execute <strong>Debug &gt; Start Debugging</strong>. You may get a message that the web server executable was not built with debugging information. Ignore this warning and click Yes to continue debugging.</p>
<p>Open a web browser and browse to your test page that calls the DoubleUp method. Your breakpoint should be hit. Step through the code, and be sure to use <strong>Debug &gt; Continue</strong> (F5) so that the web server doesn&#8217;t hang.</p>
<p>To stop debugging, go to <strong>Debug &gt; Detach All</strong> or stop the web server.</p>
<h2>Where to from here?</h2>
<p>The Zend API section of the PHP documentation provides a wealth of detailed information on the macros and functions available for extension development. And now that you&#8217;ve got your own extension up and running, you can finally make use of it! Some areas to explore are enabling your extension to accept configuration parameters from php.ini, and creating methods that accept multiple parameters, and/or optional parameters.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F09%2Fcreating-a-php-5-extension-with-visual-c-2005%2F';
  addthis_title  = 'Creating+a+PHP+5+Extension+with+Visual+C%2B%2B+2005';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/09/creating-a-php-5-extension-with-visual-c-2005/feed/</wfw:commentRss>
		<slash:comments>56</slash:comments>
		</item>
		<item>
		<title>SlickEdit 2007 For Windows Development</title>
		<link>http://blog.slickedit.com/2007/08/slickedit-2007-for-windows-development/</link>
		<comments>http://blog.slickedit.com/2007/08/slickedit-2007-for-windows-development/#comments</comments>
		<pubDate>Thu, 09 Aug 2007 14:56:51 +0000</pubDate>
		<dc:creator>Matthew E</dc:creator>
				<category><![CDATA[Code Editors]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SlickEdit Products]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=103</guid>
		<description><![CDATA[You&#8217;ve got Visual Studio®, and you mostly write applications for Windows. So why would you need SlickEdit? SlickEdit can read most Visual Studio solution and project files, and can pinch hit nicely for Visual Studio. If you just need to load up a project, make some edits, check some files in and out of source [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve got Visual Studio<sup>®</sup>, and you mostly write applications for Windows. So why would you need SlickEdit? SlickEdit can read most Visual Studio solution and project files, and can pinch hit nicely for Visual Studio. If you just need to load up a project, make some edits, check some files in and out of source control, and kick off a build, you can do all this in SlickEdit.<br />
But where SlickEdit really shines is helping you organize and edit all of that code you&#8217;ve got that doesn&#8217;t fit neatly into an application project. It all starts with using SlickEdit&#8217;s flexible and customizable project system in combination with other time-saving features.</p>
<p><strong>Managing Builds</strong></p>
<p style="float: right; margin: 0px 0px 10px 10px">Schema URL Mappings<br />
 <a rel="lightbox[pics103]" href="http://blog.slickedit.com/wp-content/uploads/2007/08/urlmappings.jpg" title="urlmappings.jpg"><img width="200" src="http://blog.slickedit.com/wp-content/uploads/2007/08/urlmappings.thumbnail.jpg" alt="urlmappings.jpg" height="103" class="imageframe imgalignleft" /></a></p>
<p>We&#8217;ve been using CruiseControl.NET and NAnt for nightly builds of our products. Both technologies use an XML file format. SlickEdit&#8217;s XML features include Auto-completion of tags and attributes, gleaned from the definitions in XSD schemas. Visual Studio also has an excellent XML editing experience, but SlickEdit allows you to customize what specific XSD schemas are used for a particular XML namespace declaration. CruiseControl.NET does not distribute an &#8220;official&#8221; schema for their namespace, mostly because the CruiseControl syntax is extensible with a plug-in architecture. By using Microsoft&#8217;s XML tools I was able to take my existing CruiseControl project files and generate a starter schema. SlickEdit&#8217;s URL Mappings allow me to then use that custom schema for document validation and auto-completion.</p>
<p>In an effort to reduce redundant code and reduce the size of the NAnt source files, many common properties and tasks used by multiple projects have been broken out into a series of include files. However, locating a property or task that is defined in an external file usually requires<a rel="lightbox[pics103]" href="http://blog.slickedit.com/wp-content/uploads/2007/08/alias.jpg" title="alias.jpg"></a> a multi-file search.</p>
<p style="float: right; margin: 0px 0px 10px 10px">Regex Evaluator<br />
<a rel="lightbox[pics103]" href="http://blog.slickedit.com/wp-content/uploads/2007/08/regexeval.jpg" title="regexeval.jpg"><img width="200" src="http://blog.slickedit.com/wp-content/uploads/2007/08/regexeval.thumbnail.jpg" alt="regexeval.jpg" height="171" class="imageframe imgalignleft" /></a></p>
<p>By using the SlickEdit Regex Evaluator I was able to craft a regular expression to search for task and property definitions. Once the expression was ready, I created a macro in Slick-C (SlickEdit&#8217;s C-like macro language)(<a href="http://blog.slickedit.com/?page_id=108">snippet</a>) to search for the word at the cursor in the current NAnt build file and any included build files. Now I have instant search across multiple files when the definition of a property or target eludes me.</p>
<p><strong>Building Installers with WIX (Windows Installer XML)<br />
</strong>WIX is an open-source toolkit from Microsoft for building Windows Installer .msi files. It too uses an XML file format. There are tools available in Wix for getting your project started and compiling your list of files to be installed, but authoring an installer still requires quite a bit of hand-editing the XML source. I use SlickEdit&#8217;s Aliases feature to provide <a href="http://blog.slickedit.com/wp-content/uploads/2007/08/aliascall.jpg">completion of code snippets </a>for commonly used Wix XML constructs. Aliases go well beyond simple insertion of prewritten code. You can configure an alias to format and auto-indent the new text, set the initial editing position, and prompt for replacement parameters.<strong> </strong></p>
<p style="float: right; margin: 0px 0px 10px 10px"><strong>Defining Aliases<br />
</strong><a rel="lightbox[pics103]" href="http://blog.slickedit.com/wp-content/uploads/2007/08/alias.jpg" title="alias.jpg"><strong><img width="200" src="http://blog.slickedit.com/wp-content/uploads/2007/08/alias.thumbnail.jpg" alt="alias.jpg" height="155" class="imageframe imgalignleft" /></strong></a></p>
<p>All of the code for the installer is placed in a custom SlickEdit project. A custom project allows you to create as many organizational folders as you need, optionally organized by physical directories or file extensions. The real power in SlickEdit projects is the ability to define custom build steps to call external tools. Since this project invokes quite a few NAnt build targets, I <a href="http://blog.slickedit.com/wp-content/uploads/2007/08/buildmenu.jpg">customized the build menu</a> by adding <a href="http://blog.slickedit.com/wp-content/uploads/2007/08/projprops.jpg">new build tools</a> to the project. These allow me to invoke NAnt to execute the build targets and display the output in the build window.</p>
<p><strong>Dabbling in PHP and MySQL, with a Side of PowerShell</strong><br />
A year or so ago, I worked on a side project to develop a content management website using PHP and MySQL. The application had to work with Internet Explorer, Firefox, and Safari browsers. Using SlickEdit allowed me to create a single project to organize the code and work with the Subversion repository located on a remote Linux hosting account. And I was able to edit the code on both a Windows XP tablet PC and my MacBook as the custom project format is identical on Windows and *Nix platforms. Customizing the project&#8217;s build commands allowed me to add shortcuts for opening pages in multiple browsers, execute MySQL scripts one the database, and transfer files via FTP to my remote hosting account.</p>
<p style="float: right; margin: 0px 0px 10px 10px">PowerShell Syntax<a href="slickedit_win/PowerShell.jpg"><br />
</a><a rel="lightbox[pics103]" href="http://blog.slickedit.com/wp-content/uploads/2007/08/powershell.jpg" title="powershell.jpg"><img width="200" src="http://blog.slickedit.com/wp-content/uploads/2007/08/powershell.thumbnail.jpg" alt="powershell.jpg" height="163" class="imageframe imgalignleft" /></a></p>
<p>SlickEdit supports dozens of languages out of the box, and has the ability to quickly add your own user-defined highlighting schemes or modify existing ones. I found that the default listing of SQL keywords didn&#8217;t include some of the MySQL keywords, but they were <a href="http://blog.slickedit.com/wp-content/uploads/2007/08/syntax.jpg">easy enough to add</a> via the Color Coding options dialog.</p>
<p>For the past year or so I&#8217;ve been using PowerShell in place of cmd.exe, and steadily building a library of scripts to automate routine tasks. But it just didn&#8217;t seem right that such a neat shell language should have to be edited without any syntax highlighting. With SlickEdit, this was easily solved. To <a href="http://blog.slickedit.com/wp-content/uploads/2007/08/powershell.jpg">set up color coding</a> for PowerShell, all I had to do was create a new language definition, specify the comment format, and add a list of keywords.</p>
<p><strong>No Code Left Behind</strong><br />
These examples only begin to scratch the surface of the features available in SlickEdit. Your code or build process doesn&#8217;t have to be a second-class citizen just because it doesn&#8217;t fit neatly into Visual Studio. For all those times you have to &#8220;just edit it in notepad&#8221; or &#8220;run this tool from the commandline&#8221;, think of how SlickEdit could save you time and hassle.</p>
<p><strong>Download Free Trial</strong></p>
<p>You can download a free trial of Slickedit 2007 here: <u><a href="http://www.slickedit.com/content/view/409/239/">SlickEdit Trial</a></u></p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F08%2Fslickedit-2007-for-windows-development%2F';
  addthis_title  = 'SlickEdit+2007+For+Windows+Development';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/08/slickedit-2007-for-windows-development/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Font Tournament</title>
		<link>http://blog.slickedit.com/2007/08/the-font-tournament/</link>
		<comments>http://blog.slickedit.com/2007/08/the-font-tournament/#comments</comments>
		<pubDate>Tue, 07 Aug 2007 12:49:21 +0000</pubDate>
		<dc:creator>Dennis B</dc:creator>
				<category><![CDATA[Code Editors]]></category>
		<category><![CDATA[Productivity]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=101</guid>
		<description><![CDATA[Here we are in the worst time of the year, that time after hockey season ends and before football season begins. The time of nothingness, boredom, spelling bees on ESPN2.
So, what do sports fans do during this down time. If they are desperate, they watch tennis, really desperate, maybe try to get into watching a [...]]]></description>
			<content:encoded><![CDATA[<p>Here we are in the worst time of the year, that time after hockey season ends and before football season begins. The time of nothingness, boredom, spelling bees on ESPN2.</p>
<p>So, what do sports fans do during this down time. If they are desperate, they watch tennis, really desperate, maybe try to get into watching a soccer game. But, if you are exceedingly desperate, you invent a new tournament sport.</p>
<p><strong>The Single Elimination Font Championship</strong></p>
<p>It&#8217;s hard to pick a really good programming font. There are a lot of fonts out there, just google for &#8220;programming font&#8221; and you will find a lot of really great fonts, and a lot of really weird fonts. But how do you pick the best font?</p>
<p>Here is my grudge about font selection dialogs. They work in one of two ways:</p>
<ol>
<li>They will only show you one font at a time.</li>
<li>They display the list of fonts in the font itself.This seems like a nice visual solution, except that it makes it impossible to<br />
decipher the font name of a symbol font or foreign language font.</li>
</ol>
<p>Finding a good programming font seems to involve a lot of trial and error. Some fonts look great in the font dialog, but do not look very good in practice. Sometimes it is hard to read vertical spacing from the font dialog. Sometimes, the plain font looks great, but it&#8217;s italic or bold variant is horrid, and you do not notice that until you are using the font in your editor.</p>
<p>In this article, I am going to outline a design for a new paradigm for font selection that overcomes some of these issues, including the problem with there being no sports on TV.</p>
<p>Picking the contestants</p>
<p>The first step is to select a set of candidate fonts. This is where you use a traditional font dialog, with one modification to the font list: checkboxes so you can pick which fonts will participate in the tournament.</p>
<p><strong>The Playoff&#8217;s</strong></p>
<p>Once you have a set of contestants, you begin the playoffs. The fonts are assigned randomly into a single-elimination bracket. A slightly more thorough variation of the system could use double-elimination brackets, but I don&#8217;t believe it&#8217;s really necessary.</p>
<p>The font contests are head-to-head. You are shown a big dialog with both fonts, their names, a size selector, and six samples side-by-side:</p>
<ol>
<li>The plain font with programmer-friendly sample text:
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">== Line before ==<br />
Aa_Bb_Cc = (l1 + O0);<br />
== Line after ==</div></td></tr></tbody></table></div>
</li>
<li>The font in bold with the same text.</li>
<li>The font in italic with the same text.</li>
<li>The font in bold and italic with the same text.</li>
<li>The font in underline with the same text.</li>
<li>An editor control with your color scheme displaying code<br />
in a language of your choice where you can paste in your<br />
own text to see.</li>
</ol>
<p>Then you select the font that you like better, and move on to the next contest. The fundamental principal is that while it may be hard to select a favorite font from a list of 100 fonts, most programmers can look at <em>two</em> fonts and pick one that they like better than the other.</p>
<p>The brackets are played out until you reach the championship round and select one favorite programming font, which you will then have the opportunity to assign the champion as your default source window font in SlickEdit. Playing out the brackets with a single-elimination tournament requires (N -1) contests where N is the number of candidate fonts participating in the tournament. Even with a huge field of 50 fonts, you could finish in 15 minutes, and you would know that the font you are using is a champion. Which will leave you plenty of time to catch that spelling bee later on ESPN2.</p>
<p><strong>Conclusion</strong></p>
<p>&#8220;It&#8217;s so crazy, it just might work.&#8221;</p>
<p>This is merely a design sketch for a font tournament system. It&#8217;s not a feature that is being developed or even in the works, just an idea. If some industrious SlickEdit user wanted to exercise his/her Slick-C skills, it would be quite easy to implement, and would be a really great user-contributed batch macro.</p>
<p>I mean, what else are you going to do with your time? It&#8217;s not like there&#8217;s any sports on TV.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F08%2Fthe-font-tournament%2F';
  addthis_title  = 'The+Font+Tournament';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/08/the-font-tournament/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Spot-welding Code: Tips for Maintaining Consistency</title>
		<link>http://blog.slickedit.com/2007/08/spot-welding-code-for-maintaining-consistency/</link>
		<comments>http://blog.slickedit.com/2007/08/spot-welding-code-for-maintaining-consistency/#comments</comments>
		<pubDate>Thu, 02 Aug 2007 13:18:51 +0000</pubDate>
		<dc:creator>Dennis B</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=99</guid>
		<description><![CDATA[Nearly all programmers are passionate about one thing &#8212; their coding style. This is kind of ironic considering this is a populace of people who, with few exceptions, could pretty much care less about style in any other aspect of their life &#8212; clothing, home decor, personal hygiene&#8230;
When I fix a bug in someone else&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Nearly all programmers are passionate about one thing &#8212; their coding style. This is kind of ironic considering this is a populace of people who, with few exceptions, could pretty much care less about style in any other aspect of their life &#8212; clothing, home decor, personal hygiene&#8230;</p>
<p>When I fix a bug in someone else&#8217;s code, sometimes I cringe at their coding style or lack thereof. On occasion, I find myself in some code that I can genuinely admire the clarity and attention to detail. I like to think of fixing bugs, in your own code, or in someone else&#8217;s, as a kind of spot-welding. The goal is to put in a clinically minimal change to fix the problem.</p>
<p>Here are a few tips for creating a clean, but strong spot-weld.</p>
<p><strong>a) Adapt to the existing code style &#8212; <em>whether good or bad</em></strong></p>
<p>Example:</p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; int foobar(int *arr[], int n) { <br />
&nbsp; &nbsp; &nbsp; &nbsp; int i,count=0; <br />
&nbsp; &nbsp; &nbsp; &nbsp; for (i=0; i&amp;lt;n; i++) { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ( arr[i] == 0 ) { <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ++count; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(arr[i]&amp;lt;0)/*fix*/ <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br />
&nbsp; &nbsp; &nbsp; &nbsp; } <br />
&nbsp; &nbsp; &nbsp; &nbsp; return count; <br />
&nbsp; &nbsp; &nbsp;}</div></td></tr></tbody></table></div>
</pre>
<p>Different brace style, indentation, spacing around punctuation, and a nearly worthless comment, &#8220;fix&#8221;. The coder who put in this fix put his ego and love for his style ahead of consistency. One thing you will find about any programmer&#8217;s style: no matter what the brace style, no matter what the spacing preferences, in general, inconsistency is ugly.</p>
<p><strong>b) Adapt to the existing naming conventions &#8212; <em>whether good or bad</em></strong></p>
<p>Granted, some people&#8217;s naming conventions are difficult, nay, impossible to recognize, but there are simple facets that can always be mimicked to improve consistency. Do they use mixed case? How do they use underscores? Do they use a naming prefix pattern? Do they use a naming suffix? What are some of the root words that represent the concepts being worked with?</p>
<p>Making your changes mesh with the existing conventions &#8212; whether good or bad &#8212; will make your changes fit in with the code around it and it shows a degree of professionalism. The code&#8217;s original author is less likely to doubt the quality of your change if it fits in.</p>
<p><strong>c) Adapt to the existing structures and coding constructs</strong></p>
<p>Example: You may use exception handling in all of your code. Programmer X may use return codes. When you do a fix in programmer X&#8217;s code, you should adapt to his constructs, even if you think they are archaic, because consistent, archaic techniques are better than inconsistent application of two very different techniques.</p>
<p>Another example: Don&#8217;t write a class to fix a bug in code that doesn&#8217;t use any classes, unless it is the only solution. Again, think of the concept of a spot-weld.</p>
<p><strong>d) Beautify the code, but don&#8217;t check in the beautifications</strong></p>
<p>If you just can not read a piece of code because of it&#8217;s style, go ahead and beautify it. But once you have a fix, revert back to the original style and merge your fix back in. This keeps the amount of change to a minimum which will help the next person who has to review the change history of that code.</p>
<p><strong>e) Leave a note behind</strong></p>
<p>When you fix a bug, leave your initials and the date with a short comment saying, &#8220;heh, I was here, I did this, and it was supposed to fix something.&#8221; That will save other people who see the code time when they are wondering who to blame (or who to give credit to). This is one area where I think it is ok to diverge from the existing code style. You should leave a note behind <em>even if it is the only comment in the entire code base.</em> You can think of it as good manners.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F08%2Fspot-welding-code-for-maintaining-consistency%2F';
  addthis_title  = 'Spot-welding+Code%3A+Tips+for+Maintaining+Consistency';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/08/spot-welding-code-for-maintaining-consistency/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Unit Testing by the Status Quo</title>
		<link>http://blog.slickedit.com/2007/07/unit-testing-by-the-status-quo/</link>
		<comments>http://blog.slickedit.com/2007/07/unit-testing-by-the-status-quo/#comments</comments>
		<pubDate>Wed, 11 Jul 2007 13:16:04 +0000</pubDate>
		<dc:creator>Dennis B</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=91</guid>
		<description><![CDATA[Have you ever been faced with code that has no tests, and every time you fix one thing, you somehow manage to break something else?
If not, then dang. You&#8217;re done reading. Go home, have a cold one.
Otherwise, you are in good company, so don&#8217;t feel so bad. Come down off the ledge.
What you really want [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever been faced with code that has no tests, and every time you fix one thing, you somehow manage to break something else?</p>
<p>If not, then dang. You&#8217;re done reading. Go home, have a cold one.</p>
<p>Otherwise, you are in good company, so don&#8217;t feel so bad. Come down off the ledge.</p>
<p>What you really want &#8212; is to be able to fix bugs in one part of the code and keep the rest of the code functioning in the same working or non-working state it was in before. But the code is woven like spaghetti, and you swear under you breath every day that the guy who wrote it should have his fingers chopped off. This mantra makes you feel better, but unfortunately it doesn&#8217;t fix any bugs.</p>
<p><strong>Unit Testing</strong></p>
<p>It&#8217;s very academic. If the code had tests, then you could fix things, run the tests and know if things break. So, biting the bullet and knowing you are volunteering to spend your foreseeable future writing incredibly boring tests, you go to your manager and you say, heh, Bob, I&#8217;m gonna take six months and write thorough unit tests for this library, then we won&#8217;t have these horrid problems anymore. Of course, Bob is not excited about losing his star developer for six months and tells you no, you have more important things to spend your time on &#8212; like fixing the bugs you create by fixing bugs.</p>
<p>Next you ask your boss, maybe we could hire an intern to write unit tests? Your boss considers the amount of damage that could do to a young, idealistic programmer&#8217;s mind, then tells you no, can&#8217;t do that &#8211;in fact, it should be illegal, it&#8217;s cruel, like chopping off people&#8217;s fingers &#8212; you start to wonder whose side he is on anyway&#8230;</p>
<p><strong>Why is it so hard?</strong></p>
<p>Why are unit tests so hard to write and also so boring to write? That&#8217;s simple. The traditional approach to unit testing tries way too hard, because the traditional approach is focused on a proof of correctness. You start writing tests for APIs and then putting in a bunch of assertions with respect to the results, and the assertions are intended to capture 100% correctness.</p>
<p>There are two major problems to this approach.</p>
<ol>
<li>It is very tedious.</li>
<li>You know that the code isn&#8217;t 100% correct to start with, otherwise, you wouldn&#8217;t be in there fixing bugs.</li>
</ol>
<p>The result is that unit testing indirectly becomes a bug-hunting exercise, because you write tests, they fail, and you are left to figure out if your test is wrong of if the code being tested is wrong. You don&#8217;t want to go home until you have unit tests that cover a large part of the library, and pass. In the process, you wind up fixing several bugs in the code you are testing &#8212; which is really not what you wanted to do &#8212; not until you had complete tests.</p>
<p>If you have good will-power and a unit testing harness that supports it, you can avoid the bug fixing trap by simply ignoring test failures until the entire test suite is complete. Most people don&#8217;t have this kind of patience, because by the time you debug your unit test, and know it&#8217;s really the code being tested that has a bug, you probably also know how to fix it, and it&#8217;s hard to resist.</p>
<p><strong>Status Quo</strong></p>
<p><em>From Webster&#8217;s dictionary: Latin: the state of which. The existing state of affairs: also status in quo.</em></p>
<p>With the exception of the bug you are fixing, the status quo is precisely what you want for the rest of the code&#8217;s behavior.</p>
<p>So, without tests, how can you know that unravelling one piece of spaghetti code will not cause a metaphorical meatball to roll off the table? Bad news time. You can&#8217;t. You need tests and you need to be able to put them together fast.</p>
<p><strong>Unit Testing by Status Quo</strong></p>
<p>A solution to this problem is to design a way to generate unit tests that feed input to the existing code and captures the results. The key here is that you are capturing results &#8212; <em>whether they are right or wrong</em> &#8212; what matters is the status quo. Forget about proof of correctness. We&#8217;re looking for proof of same-ness.</p>
<p>Put the inputs and expected results into a harness so that you can re-run the tests and compare the new results with the expected results and know when something changes.</p>
<p>Once you have this harness in place you will become a scavenger for raw input, more test cases, to feed the harness. The more the better. The harness needs food. That will become your new mantra. That other guy can keep his fingers.</p>
<p>Using this technique, you can achieve a high percentage of code coverage with a minimal amount of effort. Also, since the code now has effective unit tests, you can now pass maintenance of the problematic library to another developer and know that they have some guard rails when they go in to fix bugs.</p>
<p><strong>Managing change</strong></p>
<p>With the status quo testing harness in place, when you make changes to the code, one of three things will happen:</p>
<ol>
<li>All the tests will continue to pass. Either this is good, if the change was a refactoring or a performance improvement. Or, this is bad, it means that your fix didn&#8217;t fix anything.</li>
<li>There are tests that fail, and you expected them to fail because your fix was going to change the code&#8217;s behavior. In this case, you review the changes and regenerate the expected results.</li>
<li>There are tests that fail, and they should not have failed. Then, you know that you broke something, and you need to work more on your fix and try again.</li>
</ol>
<p><strong>Case Study</strong></p>
<p>In the span of two weeks, I was able to assemble a huge battery of tests for one SlickEdit library that had a total of around 50,000 lines of code.</p>
<p>In this instance, the code being tested just took text as input and called functions in another library. In order to isolate the test code, and capture the results, I stubbed out the functions being called and replaced them with functions that just printed out their name and arguments. For example:</p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;void doSomething(int x, int y) <br />
&nbsp; &nbsp;{ <br />
&nbsp; &nbsp; &nbsp; printf(&quot;doSomething(%d, %d)n&quot;, x, y); <br />
&nbsp; &nbsp;} <br />
&nbsp; &nbsp;void saySomething(const char *s) <br />
&nbsp; &nbsp;{ <br />
&nbsp; &nbsp; &nbsp; printf(&quot;saySomething(\&quot;%s\&quot;)n&quot;, s); <br />
&nbsp; &nbsp;}</div></td></tr></tbody></table></div>
</pre>
<p>The results looked like a big function trace:</p>
<pre>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;doSomething(1,2) <br />
&nbsp; &nbsp;saySomething(&quot;Hello&quot;) <br />
&nbsp; &nbsp;doSomething(3,4) <br />
&nbsp; &nbsp;doSomething(5,6) <br />
&nbsp; &nbsp;saySomething(&quot;Goodbye&quot;);</div></td></tr></tbody></table></div>
</pre>
<p>Comparing the expected results to the actual results using a simple line-by-line differencing algorithm allowed me to zero in on test failures and quickly review whether or not they improved the status quo or not. Building a regenerate feature into the test harness allows me to quickly update the test suite after reviewing everything.</p>
<p>Before these unit tests, due to the code&#8217;s complexity, nearly every fix was a roller-coaster ride. Since the unit tests, we have had <em>zero</em> incidents of fixes introducing new bugs. It has also given us much more freedom to undertake refactoring and cleaning up the code, since we have confidence that even sweeping changes will be unlikely to cause major breakage.</p>
<p><strong>Conclusion</strong></p>
<p>Unit testing by status quo is a simple method for insuring continued code quality with a minimal investment in test development. It does not focus on 100% proof of correctness, but instead focuses on allowing you to make continuous improvements to a code base to push it uphill towards 100% correctness without allowing for sudden backslides and unexpected breakage.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F07%2Funit-testing-by-the-status-quo%2F';
  addthis_title  = 'Unit+Testing+by+the+Status+Quo';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/07/unit-testing-by-the-status-quo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is a Power Programmer?</title>
		<link>http://blog.slickedit.com/2007/04/what-is-a-power-programmer/</link>
		<comments>http://blog.slickedit.com/2007/04/what-is-a-power-programmer/#comments</comments>
		<pubDate>Wed, 25 Apr 2007 15:11:30 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=65</guid>
		<description><![CDATA[Who’s the best programmer you ever saw? If you are like Gordon Cooper, Mercury astronaut portrayed in The Right Stuff, you might answer, “You’re looking at him!” For most of us, the image of a coworker will come to mind. If you have been a programmer long enough you will likely have a group of [...]]]></description>
			<content:encoded><![CDATA[<p>Who’s the best programmer you ever saw? If you are like Gordon Cooper, Mercury astronaut portrayed in The Right Stuff, you might answer, “You’re looking at him!” For most of us, the image of a coworker will come to mind. If you have been a programmer long enough you will likely have a group of candidates for this title, many of whom share several characteristics in common.</p>
<p>At one time, we might have used the word “hacker” to describe these people. Unfortunately, this term has become confused with those who break into computer systems, and its meaning has been weakened with connotations of inelegant or unskilled approaches. Instead, let’s call them “Power Programmers” for their particular approach to programming.So, just what is a Power Programmer? A Power Programmer is a person with a passion for coding, expertise in key areas of programming knowledge, and a bias toward working in the fastest, most efficient manner.</p>
<p><strong>Passion for Coding</strong><br />
Power programmers love to code. They code at work. They code at home. They code for the sheer thrill of making something run. Because of this passion, they have generally written a lot of code, far more than someone who is just doing it for a living.It is, perhaps, the volume of code that they write that drives much of the rest of their traits. By writing so much code they have been exposed to a broader range of problems than other programmers, giving them a greater repertoire of ready solutions. They are also faced with the same problems over and over again, giving them a greater opportunity and justification to seek the best solutions to those problems. Experience allows them to solve problems more quickly.Together, passion and practice often produce expertise, and expertise is an essential characteristic of a Power Programmer.</p>
<p><strong>Expertise in Relevant Areas of Programming</strong><br />
Expertise produces highly effective results, programs that are robust and efficient, not just something that runs. It is this expertise that puts the “power” into power programming.Programming knowledge covers a very large area, and one that is increasing every year. There is general knowledge, like knowledge of a particular language. And there is more specific knowledge, like knowledge of a particular API or a technology, like XML. You cannot say that knowledge of any specific language or technology is a requirement to be a power programmer, but you can say that there are key areas of programming knowledge that are required.</p>
<p><strong>Mastery of the Programming Domain</strong><br />
Define a programming domain as the combination of language(s) used and the APIs for the target platform. Someone can be a master of one programming domain, like writing C++ using the Microsoft Windows APIs, yet have no knowledge of another, like coding in Carbon on the Apple Macintosh. Though no single domain can be listed as required knowledge to be a power programmer, mastery of the domain in which you work is required.Power programmers have a mastery of the syntax and idioms of the programming languages they use and are sometimes referred to as “language lawyers”. If you want to know about effective parameter passing or when to favor an iterator over a for loop, go ask a power programmer. Ask an object-oriented power programmer whether they would ever make a destructor virtual, and they won’t just answer “Yes”, they’ll answer “Heck, yeah!”Programmers love to debate the relative merits of different languages, platforms, and APIs. You can still find vigorous debates over big endian versus little endian. However, no one programming domain has a monopoly on power programmers. You will find them everywhere.</p>
<p><strong>Knowledge of Computer Science Theory</strong><br />
Knowledge of the underlying principles of computer science is applicable to virtually any programming task. Power programmers show an unusual affinity for this knowledge.One important aspect of this is knowledge of data structures and when each is applicable. Power programmers love data structures. You will rarely see them so happy as when they are pondering the relative merits of a hash table versus a red-black tree. And it’s not enough for them to know how to use data structures; most are compelled to know how to implement them as well.Power programmers also have a burning interest in algorithms. They can tell you the Big O notation for all of the common sorting algorithms. They understand what makes code run faster and how to isolate and fix performance problems. Few things are as upsetting to a power programmer as an inelegant algorithm.There are certainly other important areas of knowledge to power programmers, but the core knowledge can be identified by applying the Knuth Test: if it appears in one of Donald Knuth’s volumes in The Art of Computer Programming, then it’s probably important to a power programmer. In this area of knowledge, Dr. Knuth is probably the ultimate power programmer.</p>
<p><strong>Knowledge of the Tools of the Trade</strong><br />
For programmers, the tools of the trade include editors, compilers, debuggers, make systems, source control systems, and various utilities like grep or diff. Power programmers show a mastery of these tools.Since the editor is where programmers spend most of their time, power programmers are unusually particular about their editor. Often, they have gone to great lengths to customize it to work the way they think is best. They look for facilities in an editor to avoid using the mouse, to reduce keystrokes, and to automate common operations. For a power programmer, the editor is an extension of their mind, allowing them to manipulate code with little thought about the actual mechanics used.</p>
<p><strong>Hunger to Learn</strong><br />
Regardless of the programming domain, power programmers show a hunger to learn. They suck up programming knowledge like a black hole swallowing star systems. They are often trying new techniques or experimenting with new programming languages. You frequently see them reading books about programming. This learning fuels their passion for programming and provides them with the knowledge to be more effective.</p>
<p><strong>Working in the Fastest, Most Efficient Manner</strong><br />
If you watch a power programmer work, you see a whirlwind of activity: windows opening and closing, text being manipulated, scripts being run—all at an incredibly rapid pace. This pace is possible due to their mastery of the tools they use, and it is driven by their passion for coding.Power programmers love to code. But this love is not for the act of coding—the actual typing of keywords and symbols—but for the thrill of creation. The act of coding, itself, is often viewed as tedious so they look for ways to automate frequent operations and eliminate repetitive typing.By working faster, power programmers are able to write more code. This creates a feedback loop. By writing more code, they learn more and become more effective, which allows them to work faster and write more code…If you ask a power programmer if they prefer to write fast code or write code fast, they will always answer “yes”.</p>
<p><strong>Am I a Power Programmer?</strong><br />
It is not our place to decide whether you are or are not a Power Programmer. That’s for you to decide, just as it is for you to decide your own criteria by which to judge this. The act of introspection is more important than whether or not you meet any single definition of Power Programmer. Growth in any field of endeavor depends on examining your knowledge and abilities and setting goals for areas of improvement.So, who’s the best programmer you ever saw? Even if you have a long way to go, you’ll be able to answer, “You’re not looking at him, but I’m on my way!”</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F04%2Fwhat-is-a-power-programmer%2F';
  addthis_title  = 'What+is+a+Power+Programmer%3F';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/04/what-is-a-power-programmer/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Key Binding, Command, Menu: The Golden Triangle</title>
		<link>http://blog.slickedit.com/2007/04/8/</link>
		<comments>http://blog.slickedit.com/2007/04/8/#comments</comments>
		<pubDate>Mon, 02 Apr 2007 16:37:03 +0000</pubDate>
		<dc:creator>Scott Westfall</dc:creator>
				<category><![CDATA[Productivity]]></category>
		<category><![CDATA[SlickEdit Products]]></category>

		<guid isPermaLink="false">http://blog.slickedit.com/?p=8</guid>
		<description><![CDATA[To borrow a phrase from Mr. Jinks[i], “I hate meeses to pieces”. Before you call the SPCA, let me be clear that I’m talking about computer mice and not Mus musculus, the common household mouse. Further, I should narrow my context to that of programming because in many other areas of computing the mouse is [...]]]></description>
			<content:encoded><![CDATA[<p>To borrow a phrase from Mr. Jinks[i], “I hate meeses to pieces”. Before you call the SPCA, let me be clear that I’m talking about computer mice and not <em>Mus musculus</em>, the common household mouse. Further, I should narrow my context to that of programming because in many other areas of computing the mouse is indispensable.</p>
<p>In programming, however, the mouse can be one of the greatest productivity sinkholes. Time is wasted each time you lift your hand from the keyboard to grab the mouse, and more time is wasted when you move your hand back to home row in preparation for more typing.</p>
<p>So what’s the solution? Keep your hands on the keyboard! To do this use the SlickEdit<sup>®</sup> command line and bind commonly used commands to keys.</p>
<p><strong></p>
<p>Launching Operations<br />
<br />
</strong>SlickEdit provides three ways to launch operations: key bindings, commands, and menus. OK, there are actually four, if you include icons. Since the focus of this article is how to keep your hands on the keyboard, I was going to skip that one. </p>
<p><strong></p>
<p>Key Bindings</strong> <br />
Key bindings are the fastest way to launch an operation. They can be pressed at any time while editing. A key binding associates a key sequence with a command. A key sequence is a series of key strokes. Anything you do frequently should be bound to an easily remembered key sequence.</p>
<p>For example the key sequence Ctrl+A means hold down the Control key, typically labeled “Ctrl” on most keyboards, and press the A key. The letter A is represented as an uppercase letter, but this does not mean that you are to press the Shift key. If you are supposed to press the Shift key, the sequence will be written as Ctrl+Shift+A.  We use the uppercase A to match the letter on the keyboard.</p>
<p><strong></p>
<p>Commands<br />
<br />
</strong>Commands are useful for less frequently used operations or operations that take arguments. They are executed from the SlickEdit command line and are nearly as fast as key bindings. Press the Escape key (in most emulations) to activate the command line, which is displayed at the bottom of the SlickEdit application window.  </p>
<p style="text-align: center">
<p align="center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image001.jpg" title="image001.jpg"><img width="96" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image001.thumbnail.jpg" alt="image001.jpg" height="73" class="imageframe imgalignleft" /></a> </p>
<p align="center">  <em>Figure 1, SlickEdit with Command Line</em></p>
<p>It offers a full command history and completions for command names and arguments. Use the arrow keys or the mouse to scroll through previous commands. As you type, a list of possible completions is displayed. Use the arrow keys or mouse to select a completion. SlickEdit stores recorded macros as commands. You can also use Slick-C to write new commands. Use the <strong>_command</strong> keyword to identify a macro as a command. Any command can be bound to a key sequence for faster launching. </p>
<p><strong></p>
<p>Menus<br />
<br />
</strong>Menus are accessed via the mouse or a keyboard shortcut. Menus are great for infrequently used items that may not be worth a key binding. They are also helpful to learn about new capabilities. But if you use an operation frequently, you will be more productive by binding it to a key sequence or launching it from the command line. Many menus list a keyboard shortcut to launch the operation. This is just the key binding for the associated command. So when you use a keyboard shortcut, you are really just using a key binding. </p>
<p>You can also operate the main menu through hotkeys. Enable the use of hotkeys by selecting <strong>Tools &gt; Options &gt; General</strong>, selecting the General tab, and putting a check in “Alt menu hotkeys”. This will be selected by default in many emulations. Once enabled, pressing the Alt key will display an underscore beneath each menu option, indicating the letter to press to activate that option. This is not as fast as key bindings, but it does keep your hands on the keyboard and is much faster than using the mouse. In some cases the menu hot key sequence is a good mnemonic for the command. For example, Alt+P, E (to bring up <strong><u>P</u>roject &gt; Prop<u>e</u>rties</strong>) may be easier to remember and type than binding project-edit to Ctrl plus some function key. </p>
<p><strong></p>
<p>Icons<br />
<br />
</strong>SlickEdit presents icons in a series of toolbars related to different tasks. Toolbars can be customized with an extensive set of additional icons. Icons are useful for die-hard mouse users or for setting up infrequently used operations for which you have a hard time remembering the associated command or key binding. </p>
<p><strong></p>
<p>The Golden Triangle<br />
<br />
</strong>The three methods (excluding icons) to launch an operation are related, forming the Golden Triangle of operation launching. If you know how to execute an operation with one of these, you can easily configure SlickEdit to launch the operation using the other two methods. Commands form the base for the other two…which is why it is shown as the apex of the triangle (Damn it, Jim, I’m an engineer, not an artist!). Maybe I should have used a Golden U or something. <br />
 </p>
<p style="text-align: center">
<p align="center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.jpg" title="image003.jpg"><img width="128" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.thumbnail.jpg" alt="image003.jpg" height="91" class="imageframe imgalignleft" /></a></p>
<p align="center"><em>Figure 2 the Golden Triangle; behold its majesty!</em></p>
<p align="center">
<p align="center">
<p><strong>From Key Binding to Command<br />
<br />
</strong>Sometimes you may want to change the key sequence to which an operation is bound. You first need to find the command associated with that key sequence. Use the <strong>what-is</strong> command from the SlickEdit command line or select <strong>Help &gt; What Is Key</strong> from the main menu. The command line will be replaced with the prompt, “What is key:” Enter the key sequence in question, like Ctrl+A (hold down the Control key and press A), and SlickEdit displays the associated command. In CUA emulation, SlickEdit will output, “Ctrl+A runs the command select-all”. You can use the same approach to determine the commands associated with mouse events. After you run what-is, click any mouse button and you will be prompted with a list of mouse events. Select one from the list and SlickEdit displays the associated command. For example, if you select mbutton-down in CUA emulation, SlickEdit will output, “MButtonDn runs the command mou-paste”. </p>
<p><strong></p>
<p>From Command to Key Binding<br />
<br />
</strong>To find the key binding for a command, use the where-is command or select Tools &gt; Options &gt; Key Bindings from the main menu. The where-is command works just like what-is, except you type in the command name and it outputs the key sequence. The Key Bindings dialog displays a list of the commands. You can scroll through the list or search for a command by typing the command in the text box at the top. The key binding for the selected command is displayed in the dialog.   </p>
<p style="text-align: center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.jpg" title="image003.jpg"></a><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image005.png" title="image005.png"><img width="128" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image005.thumbnail.png" alt="image005.png" height="89" class="imageframe imgalignleft" /></a></p>
<p align="center"><em>Figure 3, Key Bindings Dialog    </em></p>
<p align="center">
<p align="left"><strong>Modifying Key Bindings<br />
<br />
</strong>The Key Bindings dialog can also be used to set a key binding. Type the command in the Command field, or select one from the list. Then click the “Add Key or Mouse Click” button. Now type the key sequence you want to use. For example, to bind a command to Ctrl+A, hold down the Control key and press A. To bind a command to a mouse event, click any mouse button and then select the appropriate event from the list. When you are finished, click the <strong>Bind</strong> button. To exit the dialog, click <strong>Done</strong>.</p>
<p align="left"><strong>From Menu to Command</strong> <br />
If the menu entry displays a keyboard shortcut, you can quickly find the associated command using what-is and entering the key sequence. If the menu entry does not display a shortcut, then finding the command for an entry involves a little more work. </p>
<p>SlickEdit provides a convenient UI under <strong>Macro &gt; Menus</strong> that allows you to view and modify menus in SlickEdit. To find commands for the items on the main menu, select “_mdi_menu” from the list and then click the <strong>Open</strong> button. You are presented with a menu hierarchy that you can expand to find the menu entry in question. Once selected, information about the entry is displayed including the command executed. You can use this menu to add or change the shortcut for a menu item. Doing so has the same effect as using the Key Bindings dialog to bind the menu entry’s command to a key sequence.   </p>
<p style="text-align: center"><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image003.jpg" title="image003.jpg"></a><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image005.png" title="image005.png"></a><a rel="lightbox[pics8]" href="http://blog.slickedit.com/wp-content/uploads/2007/04/image007.jpg" title="image007.jpg"><img width="96" src="http://blog.slickedit.com/wp-content/uploads/2007/04/image007.thumbnail.jpg" alt="image007.jpg" height="73" class="imageframe imgalignleft" /></a></p>
<p align="center"><em>Figure 4, Menu Editor</em></p>
<p>Some menu entries are added dynamically by SlickEdit, so you may have to search the code to find the associated command. One example of this is <strong>Build &gt; Java Options</strong>, which is only present when a Java project is active. Unfortunately, finding the associated commands for these entries can be very difficult and not easily covered in an article like this.</p>
<p><strong></p>
<p>Context Menus</strong> <br />
It is also easy to find the commands in the context menu for the editor window. The context menu, itself, contains an entry to “Edit This Menu”. Selecting this option brings up a dialog that lists the menu entries and associated information, including the command. Use this dialog to modify the context menus. Note that there are two context menus for the editor window: one when a selection is made and one when no selection is made. You can view or change the function that is used for these menus by selecting <strong>Tools &gt; Options &gt; File Extension Setup</strong> and selecting the Advanced tab.<br />
<strong></p>
<p>From Key Binding to Menu and Back</strong> <br />
Menu entries map to key bindings through commands, so key bindings are not directly associated with menu entries. To map from a key binding to a menu or vice versa, you need to look up the associated command. That Golden U is looking better all the time!</p>
<p><strong></p>
<p>Customizing Toolbar Icons</strong> <br />
The focus of this article has been to help you keep your hands on the keyboard, so icons weren’t included in the Golden Triangle. Besides, then I would have needed a Golden Square or some other form of rhombus, and that just doesn’t sound cool. You may find it helpful to change the set of displayed toolbars, add or remove icons, or change the behavior for an icon. SlickEdit uses the term “toolbar” to refer to both icon bars and tool windows. To change the set of displayed toolbars, select <strong>View &gt; Toolbars</strong> and check/uncheck one of the listed toolbars. The list is divided into two groups. The top group is comprised of tool windows, like the Symbol view and the Projects view. The bottom group is made up of icon bars. </p>
<p>Additional options are available on the Toolbar Customization dialog by selecting <strong>View &gt; Toolbars &gt; Customize</strong>. The Toolbars tab provides a way to control the visibility of the toolbars. The Toolbars tab allows you to set options for which toolbars are visible, whether they are dockable, etc. </p>
<p>The Categories tab displays the complete set of available icons. These can be added to any icon toolbar by dragging them to the desired location. All of the icons have pre-defined behaviors, except the set in the “User Definable Tools” category. Use these to add your own functionality. </p>
<p>Each icon has an associated command that defines what happens when it is clicked. To view or change that command, right-click on the icon and select Properties. The icon needs to be located in a toolbar to do this. You cannot access the properties for an icon in the Toolbar Customizations dialog.  </p>
<p><strong></p>
<p>“Exit, Stage Left”<br />
<br />
</strong>OK, that one is a Snagglepuss reference<a name="_ednref2" title="_ednref2"></a>[ii]. Whatever angst I previously expressed for mice has now been transferred to the Golden Polygon of Unspecified Dimensions. Regardless of the shape, you now have the tools you need to configure SlickEdit to work the way YOU think it should, using the key bindings you find natural. This is one of the essential steps in being a true power programmer.<br />
 </p>
<hr />    </p>
<p class="MsoEndnoteText"><a name="_edn1" title="_edn1"></a>[i] Mr. Jinks, sometimes called “Jinks the cat”, appeared in the “Pixie and Dixie” cartoons as part of “The Huckleberry Hound Show”, by Hanna and Barbera.</p>
<p class="MsoEndnoteText"><a name="_edn2" title="_edn2"></a>[ii] Snagglepus is another of Hanna-Barbera’s cartoon characters.</p>
<script type="text/javascript">
  addthis_url    = 'http%3A%2F%2Fblog.slickedit.com%2F2007%2F04%2F8%2F';
  addthis_title  = 'Key+Binding%2C+Command%2C+Menu%3A+The+Golden+Triangle';
  addthis_pub    = '';
</script><script type="text/javascript" src="http://s7.addthis.com/js/addthis_widget.php?v=12" ></script>
]]></content:encoded>
			<wfw:commentRss>http://blog.slickedit.com/2007/04/8/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
