<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-22108880</id><updated>2011-04-21T13:46:00.726-07:00</updated><title type='text'>Shallow Waters</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://shallow-waters.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22108880/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://shallow-waters.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Will</name><uri>http://www.blogger.com/profile/03513142124328025961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-22108880.post-116342079860075731</id><published>2006-11-13T04:11:00.000-08:00</published><updated>2006-11-13T04:26:38.643-08:00</updated><title type='text'>Delphi Menus &amp; Submenus</title><content type='html'>This morning I hit a problem with the way events are fired in Delphi menus.&lt;br /&gt;&lt;br /&gt;What I wanted was a menu, populated with a set of reports with options to view or edit a report. Rather than forcing the user to expand a submenu everytime they wish to view a particular report I wanted to view the report as soon as the user clicks on the item and provide a sub-menu for each report containing the edit option; i.e. the menu would be structured as follows:&lt;br /&gt;&lt;br /&gt;Reports&lt;br /&gt;-&gt; Quotes -&gt; Edit&lt;br /&gt;-&gt; Outstanding Orders -&gt; Edit&lt;br /&gt;-&gt; Completed Orders -&gt; Edit&lt;br /&gt;&lt;br /&gt;The problem that I discovered is that the OnClick event of a menu with sub-items is fired when the sub-menu is expanded - even if the user does not click at this point - and no event is fired when the user clicks on the parent item. This resulted in my application trying to produce a report everytime the user hovered over an item in this menu. Ah well, I guess I will just have to add 'View' and 'Edit' into the submenu for each item.&lt;br /&gt;&lt;br /&gt;In truth I was a little unsure about using menus in this way any way. I can't imagine many other situations where you would want to create a menu item that both owns a sub-menu and has behaviour of its own. Having a menu containing only one item seems wrong as well. Perhaps there is something somewhere in the Apple Human Interface Guidelines which explictly forbids such a thing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22108880-116342079860075731?l=shallow-waters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shallow-waters.blogspot.com/feeds/116342079860075731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22108880&amp;postID=116342079860075731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22108880/posts/default/116342079860075731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22108880/posts/default/116342079860075731'/><link rel='alternate' type='text/html' href='http://shallow-waters.blogspot.com/2006/11/delphi-menus-submenus.html' title='Delphi Menus &amp; Submenus'/><author><name>Will</name><uri>http://www.blogger.com/profile/03513142124328025961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22108880.post-115514011208259222</id><published>2006-08-09T08:35:00.000-07:00</published><updated>2006-08-09T09:15:12.116-07:00</updated><title type='text'>Quick post about Delphi packages</title><content type='html'>Over recent months (notably this afternoon) I've been regularly banging my head against a brick wall trying to wrap it around Delphi packages, design-time packages and installing packages. Finally, I believe that I have got this clear in my head.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What does it mean to install a package?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;When you install a package, Delphi keeps a reference to the .bpl of the package in its settings (I presume that this means in the registry but I don't actually know where). When the package is installed and everytime Delphi launches subsequently it calls all Register procedures.&lt;br /&gt;&lt;br /&gt;Typically the package is used as a placeholder for one or more components, in which case the Register procedure will simply add the components to the IDE.&lt;br /&gt;&lt;br /&gt;Design-time packages can also peform other actions through the OTA API - basically allowing installation of the package to manipulate the IDE.&lt;br /&gt;&lt;br /&gt;So there you have it - an installed package simply is a package that has it's Registry procedures invoked whenever Delphi starts.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What does it mean when a package 'requires' another package&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;As far as I can see, .pas file on the library path is available to any other unit. Additionally any unit which is wrapped up inside a Delphi Compiled Package (DCP) file is also available to any other unit. However linking implicitly into another package is considered bad form so Delphi warns you when it detects this. You can get rid of the warning if you add an explicit 'requires' from the client package to the used package.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Confused Yet? Let me tell you a story&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The main area where I have become confused is when you have multiple copies of the DCP and BPL files available on the library path. By default, the Delphi library path has entries for $(DELPHI)\bin, $(DELPHI)\lib &amp; $(DELPHI)\Projects\Bpl and will not warn you if these directories contain different version of the same files.&lt;br /&gt;&lt;br /&gt;The first problem that I had installed a package with multiple versions on the library path. The actual installed package was in $(DELPHI)\Projects\Bpl but there was an out of date version in $(DELPHI)\lib (someone, who was probably me, must have changed this without thinking at some stage). This appeared to be causing Delphi some confusion as the new feature I had added to my component was not visible in the IDE but the new methods and properties could be accessed programatically.&lt;br /&gt;&lt;br /&gt;Dutifully I closed down Delphi, deleted the offending BPL &amp; DCP files and tried again. Still the same problem. I recompiled and reinstalled the the package. Still the same problem!&lt;br /&gt;&lt;br /&gt;After rebooting, reinstalling and retesting about 50 times I finally spotted the problem.&lt;br /&gt;&lt;br /&gt;We had split up our component library into a large run-time only package that housed all the actual components and a small design-time package that actually did the registering. I had been rebuiding the component package, rebuilding the design-time package and the reinstalling. The one thing I hadn't noticed was that the underlying component package also had an out of date duplicate in the $(DELPHI)\lib folder. This was being ignored by the editor and compiler because the top directory in the library path was referring to a folder containing all the latest DCUs but it was not being ignored when the package was installed.&lt;br /&gt;&lt;br /&gt;You have been warned - don't do stupid things and you'll be fine!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22108880-115514011208259222?l=shallow-waters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shallow-waters.blogspot.com/feeds/115514011208259222/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22108880&amp;postID=115514011208259222' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22108880/posts/default/115514011208259222'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22108880/posts/default/115514011208259222'/><link rel='alternate' type='text/html' href='http://shallow-waters.blogspot.com/2006/08/quick-post-about-delphi-packages.html' title='Quick post about Delphi packages'/><author><name>Will</name><uri>http://www.blogger.com/profile/03513142124328025961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22108880.post-113935651579297493</id><published>2006-02-07T14:13:00.000-08:00</published><updated>2006-02-07T16:03:43.956-08:00</updated><title type='text'>Test Driven Development Jottings</title><content type='html'>In my recent paddling I've been considering how best to introduce test driven development to some of my programs and how to overcome previously encountered problems. My only previous attempt at using test driven development in a serious way I abandoned as deadlines approached and rapid functionality changes were required. Additionally, I have tried to introduce some unit testing to smaller parts of applications and although the testing has not been entirely unsuccessful I've been left feeling that the testing code is unnecessary clutter within the sources, rather than an integral part of all of the work. The books that I have read &lt;span style="font-size:78%;"&gt;(1)&lt;/span&gt;have offered much explanation about why unit testing is useful, a general approach to test-driven development and some of the technical details about using tools such as JUnit but they lack much insight into good test design techniques.&lt;br /&gt;&lt;br /&gt;If you are an experienced test-driven developer who could offer me insight then your comments would be gratefully appreciated.&lt;br /&gt;&lt;br /&gt;If you are a humble novice such as myself then I hope you find my experiences and ideas useful.&lt;br /&gt;&lt;br /&gt;There are a number of reasons why I think that I have had problems:&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;1. Laziness&lt;/strong&gt;&lt;br /&gt;Quite simply I'd rather dive strait into coding rather than write out a set of test cases.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;2. Time pressure&lt;/strong&gt;&lt;br /&gt;Writing unit tests offer medium and long term benefits (i.e. write tests now and benefit when I revisit the same code in the future) but there is no immediate benefit to writing a unit test. At work, when I'm looking to get the current task out of the way and move onto the next within a few hours there's no incentive to double the development time by writing tests first. Similarly, in my personal projects I normally struggle to find more than a couple of hours every few days, so I'm normally focused on getting some results out quick before I go to bed.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;3. Programming style&lt;/strong&gt;&lt;br /&gt;I've always programmed in object oriented languages, using object oriented designs but I've never got into the habit of the truly extreme style of writing lots of small classes and short classes advocated in extreme programming. My programs tend be rather like a brick wall, with one layer of classes cemented on top of the previous - with the high level classes completely reliant on those in the lower layers. Thus my programs require really complex fixtures to be setup before the high level components can be tested.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;4. Tests are coupled to the class interfaces that you design&lt;/strong&gt;&lt;br /&gt;In an early experiment with unit testing I wrote a series of tests for a single method - trying to find all of the cases that were likely to cause problems. The problem was that twice I had to change the parameters required by the method and, of course, both times I had to rewrite all of the tests. In hindsight there are several things that would have helped with this:&lt;br /&gt;a) Design the interface better in the first place&lt;br /&gt;b) Use method overloading and default parameters to eliminate the need to rewrite method calls when parameter lists are changed&lt;br /&gt;c) Write a set of wrapper classes and methods within the testing code to shield the individual tests from minor changes to interfaces&lt;br /&gt;I'm not entirely satisfied with any of these solutions. Trying to predict the future when designing interfaces in order to anticipate what new parameters may be required is a hopeless task, although it is reasonable to think through a method interface to the point where it is less likely that a change will be required.&lt;br /&gt;&lt;br /&gt;I'm also not a big fan of using default parameters and method overloading simply to save rewriting calls to a method when the interface changes as these constructs often make code less readable.&lt;br /&gt;&lt;br /&gt;Wrapper classes would solve the problem without adversely affecting the design of the existing code but seems like overkill for writing simple tests.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;5. Tests can introduce unwanted constraints on the behavior of the program&lt;/strong&gt;&lt;br /&gt;With some tests that I have written I have found it hard to avoid making them excessively strict and I am concerned that slight changes will cause my tests to break when in fact the changes I have made were perfectly valid.&lt;br /&gt;In particular at work I have written some a simple CAM add-on to RoofWright which exports DXF drawings. In order to do this I used a set of classes to model generic DXF drawings and wrote a series of DXF builder classes to map from my domain model to the required DXF. At the time I first wrote this there was no constraints on the exact layout of the drawing (the user could worry about that) so I didn't want to introduce constraints of this kind into the testing (i.e. by asserting that the coordinates of the DXF entities matched some exact values). If I ever had to introduce some way of laying out the drawings by translating all of my entities the tests would fail even though the change was perfectly reasonable.&lt;br /&gt;&lt;br /&gt;In order to get around this I wrote some extra methods in my testing to allow me to ensure that check only that the generated drawing was a geometric translation of the original test data. This solution worked although it made the testing classes themselves more complex.&lt;br /&gt;&lt;br /&gt;Perhaps at some point I'll manage to overcome these problems and become a better programmer!&lt;br /&gt;&lt;br /&gt;Notes:&lt;br /&gt;(1) I'm mainly referring to Kent Beck's books on XP, and Refactoring by Martin Fowler but I have also glanced at books about test driven development&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22108880-113935651579297493?l=shallow-waters.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shallow-waters.blogspot.com/feeds/113935651579297493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22108880&amp;postID=113935651579297493' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22108880/posts/default/113935651579297493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22108880/posts/default/113935651579297493'/><link rel='alternate' type='text/html' href='http://shallow-waters.blogspot.com/2006/02/test-driven-development-jottings.html' title='Test Driven Development Jottings'/><author><name>Will</name><uri>http://www.blogger.com/profile/03513142124328025961</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
