{"id":593,"date":"2009-10-17T11:31:21","date_gmt":"2009-10-16T23:31:21","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=593"},"modified":"2009-10-17T18:46:51","modified_gmt":"2009-10-17T06:46:51","slug":"great-things-in-delphi-2010","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/593\/","title":{"rendered":"Great Things in Delphi 2010"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">7<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>Perhaps apart from attributes and the significant changes in the area of RTTI in Delphi 2010, there really isn&#8217;t much in the way of &#8220;HEADLINE NEWS&#8221; in this release.  But that doesn&#8217;t mean there isn&#8217;t lots to appreciate, some of it dangerously subtle.<\/p>\n<p><!--more--><\/p>\n<p>&#8220;Dangerous&#8221; because unless someone draws your attention to it, you might not even notice it.<\/p>\n<p>As they occur to me I shall discuss some of these, usually with some explanation of why I think they are great, rather than just listing off the feature itself.  I shall also present some ideas that these new features have given me for yet further improvements in some areas.<\/p>\n<p>So first up in this occasional series&#8230;.<\/p>\n<h1>Drag\/Drop &#8220;Gutter-Balls&#8221;<\/h1>\n<p>I used the term &#8220;gutter-ball&#8221; recently when talking about this feature, so perhaps I&#8217;d better explain what they are before getting into dragging and dropping them.<\/p>\n<p>&#8220;Gutter balls&#8221; are what I call those decorations that pop-up in the &#8220;gutter&#8221; alongside your code editor. \u00a0Breakpoints (the red dots), bookmarks (the numbered squares), the execution point indicator (when stepping through code in the debugger) etc etc.<\/p>\n<p>&#8220;Balls&#8221; is a bit of a misnomer because many of these decorations aren&#8217;t actually round, like a ball, but why let strict linguistic accuracy get in the way of a good nick-name?<\/p>\n<p>Anyway, in Delphi 2010 many of these decorations can now be freely dragged and dropped. \u00a0This to me a &#8220;a big deal&#8221;.<\/p>\n<h2>Breakpoints<\/h2>\n<p>I often use conditions on breakpoints, be that a pass count or some explicit condition expression to control when\/if a breakpoint is active.<\/p>\n<p>during a debugging session I&#8217;ll often find myself honing in on a bug, removing breakpoints and adding new ones as I get closer and close to where I suspect there to be a problem. \u00a0Often the conditions on those new breakpoints are the same &#8211; or very similar &#8211; to those that I have removed, and I have to remember to setup those conditions on those new breakpoints each time.<\/p>\n<p>Now I can simply <strong>drag<\/strong> an existing breakpoint, complete with conditions, and simply <strong>drop<\/strong> it where I now wish it to be. \u00a0This may not save me a lot of actual time in absolute terms but it sure is going to make my debugging life easier.<\/p>\n<h2>The Execution Point<\/h2>\n<p>This is a potential minefield, but also a potential God-send.<\/p>\n<p>Just as with breakpoints, when debugging and &#8220;stopped&#8221; on some line of code you can now <strong>drag<\/strong> the execution point and <strong>drop<\/strong> it somewhere else. \u00a0When you resume execution or step, your code will execute from that new point.<\/p>\n<p><strong><em>WOAH<\/em><\/strong>! \u00a0Hold on a minute, isn&#8217;t that, like&#8230; <span style=\"color: #ff0000;\"><strong><em><span style=\"text-decoration: underline;\">DANGEROUS<\/span><\/em><\/strong><\/span>!?<\/p>\n<p>Absolutely. \u00a0You could make a real mess of things by moving the execution point too far. \u00a0In particular if you move it from within one function body to inside another, then your stack is almost certainly going to become corrupt, not to mention the fact that the new function body will not have been invoked with the necessary parameter assignments to registers etc etc so what happens when you resume execution is pretty unpredictable (some shortcut to restore the execution point to the &#8220;real&#8221; current execution point might be useful for those times when a thoughtless drag and a reckless drop create such a situation inadvertently).<\/p>\n<p>You really do not want to move the execution point too far. \u00a0But sometimes it is undeniably useful to be able to move it <em>just a little<\/em>.<\/p>\n<p>Let us imagine you are debugging&#8230; you find yourself stopped on a line of code that you suddenly realise might be responsible for all your problems. \u00a0Perhaps you forgot some trivial parameter check and are about to &#8211; incorrectly &#8211; call some function with a NIL parameter. \u00a0Or perhaps you realised that your code just called a function with the wrong value in some variable passed as a parameter.<\/p>\n<p>You know that you need to fix that, and you&#8217;ll come back to it shortly, but for now you&#8217;d like to see if that change would actually fix your problem. \u00a0If only you could prevent the code from calling that function, or fix the value of that variable and call that function again with the correct parameter value &#8211; \u00a0just as the changes in either case you are going to make would result in.<\/p>\n<p>Well now you can.<\/p>\n<p>Simply pick up the execution point and advance it FORWARD, beyond that function call, or edit the variable value (via the <strong>Expression Evaluator<\/strong> as usual &#8211; <strong>Ctrl+F7<\/strong>) and move the execution point BACKWARD, to repeat the call.<\/p>\n<p>With Delphi&#8217;s lightning fast compilation performance, maybe it&#8217;s not such a big deal to have to halt the program, make the change, recompile and then re-test. \u00a0But perhaps the application in question can&#8217;t simply or safely be <strong>Ctrl-F2<\/strong>&#8216;d and has to be allowed to proceed through some lengthy shutdown procedure, and\/or maybe recreating the problem to get to this point in the code to test it is non-trivial.<\/p>\n<p>Sometimes a &#8220;quick fix&#8221; is just what the debugger ordered.<\/p>\n<h2>Bookmarks<\/h2>\n<p>This is not such a big deal &#8211; bookmarks were already very easily moved from one location to another simply by redeclaring the new location of the bookmark via the appropriate keyboard shortcut (<strong>Ctrl+Shift+&lt;<em>0..9<\/em>&gt;<\/strong>).<\/p>\n<p>However, this might provide the inspiration for extending these newly movable gutter-balls even further&#8230; beyond their current limitations.<\/p>\n<p>I will say however that a distinct improvement in this areas is the visual representation of bookmarks &#8211; these now much more clearly identify the number of the bookmark associated with them.<\/p>\n<h1>Limitations<\/h1>\n<p>The biggest limitation is that you can&#8217;t drag\/drop between different tabs in the editor. \u00a0If whilst debugging I step-in to a routine in another unit and realise that I now want my breakpoint in that routine I cannot drag it and drop it from one unit to the other.<\/p>\n<p>Dragging and dropping the execution point between units is not a great idea &#8211; as mentioned, even moving it between different functions in the\u00a0<em>same<\/em> unit is asking for trouble as it is, so let&#8217;s not worry about those.<\/p>\n<p>Another problem is that when the execution point is on a line with a breakpoint you can&#8217;t get at the breakpoint to drag it! \u00a0Any drag operation picks up the execution point, not the breakpoint &#8220;behind&#8221; it! \u00a0If you want to move the breakpoint this creates a rather messy situation where you have to drag the execution point out of the way, drag\/drop the breakpoint, then drag the execution point back to where it was.<\/p>\n<p>Yuck.<\/p>\n<h1>Exceeding The Limitations &#8211; Breakpoints<\/h1>\n<p>For breakpoints there are two ways I can think of to get around the inability to drag\/drop between units, and one of those would also fix the &#8220;execution point hides my breakpoint&#8221; problem:<\/p>\n<ul>\n<li>When dragging, if the mouse moves over an editor tab then switch the editor to that tab (you will notice when trying to drag breakpoints that &#8220;tabs&#8221; themselves are already &#8220;active&#8221; dropspots when dragging, in a way that the tab strip itself is not).<\/li>\n<\/ul>\n<p>This doesn&#8217;t really need any explanation. \u00a0The next idea will need a little more detailed exploration though I think&#8230;<\/p>\n<ul>\n<li>Provide some way of identifying breakpoints, perhaps by simply assigning some number to them, as with\u00a0bookmarks. \u00a0<strong>Ctrl<span style=\"text-decoration: underline;\">+Alt+<\/span>Shift+&lt;<em>0..9<\/em>&gt;<\/strong> might be available for this. \u00a0Other key combinations could work but for the purposes of exploring the suggestion below, let&#8217;s assume this combination for now.<\/li>\n<\/ul>\n<p>Pressing <strong>Ctrl+Alt+Shift+&lt;<em>0..9<\/em>&gt;<\/strong> where no breakpoint is currently assigned to that number should drop a new breakpoint at the current location or, if there are existing un-numbered breakpoints defined, pop-up a list of those breakpoints (&#8220;anchored&#8221; in the gutter, and keyboard navigable by default) to allow you to choose one to move to that location and assign the appropriate number to it.<\/p>\n<p>Pressing <strong>Ctrl+Alt+Shift+&lt;<em>0..9<\/em>&gt;<\/strong> for a breakpoint that is already assigned to that number would simply move the appropriate breakpoint to the current location.<\/p>\n<p>Breakpoint number assignments could of course be managed more directly via the existing Breakpoints list window in the IDE.<\/p>\n<p>Pressing <strong>Ctrl+Alt+&lt;<em>0..9<\/em>&gt;<\/strong> (i.e. without the <strong>Shift<\/strong> modifier) for a breakpoint that is already assigned to that number would take you to the current location of that breakpoint, acting like a bookmark (I often find myself dropping a bookmark alongside a breakpoint).<\/p>\n<p>10 may seem a rather limiting number for the total of such identified breakpoints, but in my experience if you have that many active breakpoints then in my view you aren&#8217;t debugging very effectively. \u00a0A potentially contentious view, but I have yet to encounter a situation, even in highly complex problems, where more than 4 or 5 breakpoints are actively useful, and usually it&#8217;s only 2 or 3.<\/p>\n<p>In fact, I think this &#8220;numbered breakpoint&#8221; idea has merit beyond being a work around for moving breakpoints between units.<\/p>\n<h1>Above and Beyond- Further Debugger Enhancements<\/h1>\n<p>With the ability to modify variable values via <strong>Expression Evaluation<\/strong>, and the ability to easily move the execution point around, we are pretty much as close to being able to modify our code &#8220;on the fly&#8221; during a debugging session as it&#8217;s likely to be possible to get with a fully compiled runtime\/debugging environment.<\/p>\n<p>A couple of fairly minor additions would make it even easier to effect that sort of behaviour and further enhance the debugging tools imho.<\/p>\n<ul>\n<li>Provide a <strong>Skip Over<\/strong> debugger shortcut key\/toolbar command. \u00a0The existing\u00a0<strong>Step Over<\/strong> &#8211;\u00a0<strong>F8<\/strong> &#8211; allows you to execute the line of code at the current execution point and resume debugging at the next source line. \u00a0<strong>Skip Over<\/strong> &#8211; <strong>Shift+F8 <\/strong>perhaps?<strong>&#8211; <\/strong>would allow you to advance the execution point over that same line of code without executing it.<\/li>\n<\/ul>\n<ul>\n<li><span style=\"text-decoration: line-through;\">A <\/span><strong><span style=\"text-decoration: line-through;\">Step Out<\/span><\/strong><span style=\"text-decoration: line-through;\"> command would also be useful. \u00a0This would execute the code up to the end of the current function or procedure. \u00a0i.e. equivalent to dropping a breakpoint at the end of the the procedure, running to that breakpoint, then removing the breakpoint &#8211; something I find myself doing a LOT when I find myself in a RTL function that I really am not interested in, when debugging with <\/span><strong><span style=\"text-decoration: line-through;\">Debug DCU&#8217;s<\/span><\/strong><span style=\"text-decoration: line-through;\">.<\/span><span style=\"color: #ff0000;\"> [Update: Already present since at least Delphi 7! \u00a0I don&#8217;t know how I&#8217;ve not noticed that before! \u00a0It uses Shift+F8 already, so a &#8220;Skip Over&#8221; would need to use something else. \u00a0Thanks to msohn and windwings for pointing that out]<\/span><\/li>\n<\/ul>\n<ul>\n<li>Provide a <strong>Skip Out<\/strong> command<strong>.<\/strong> This would work like <strong>Step Out<\/strong> but would jump to the end of the current function\/procedure <em>without executing the code<\/em> between there and the current execution point. \u00a0Equivalent to an <strong>EXIT<\/strong> call being made at the current execution point (for that reason, perhaps it should instead <strong>Skip<\/strong> to any <strong>finally<\/strong> block if the current execution point is within a <strong>try\/finally<\/strong>&#8230; I don&#8217;t know if that&#8217;s possible for the debugger to determine however).<\/li>\n<\/ul>\n<p>And finally&#8230;<\/p>\n<ul>\n<li>Make the <strong>Expression Evaluator<\/strong> window a modeless, dockable panel and\/or allow in-place editing of <strong>watchlist<\/strong> or <strong>local variable<\/strong> values.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">7<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Perhaps apart from attributes and the significant changes in the area of RTTI in Delphi 2010, there really isn&#8217;t much in the way of &#8220;HEADLINE NEWS&#8221; in this release. But that doesn&#8217;t mean there isn&#8217;t lots to appreciate, some of it dangerously subtle.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[95,292,78],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-9z","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":760,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/760\/","url_meta":{"origin":593,"position":0},"title":"Platform Independence Version Dependencies in the XE2 RTL","date":"14 Sep 2011","format":false,"excerpt":"So I have spent about a week now with XE2 and FireMonkey and thought I would share some of the experience so far. After an initial peek and poke around, the first order of business for me was to migrate some of my existing code to the new RTL. First\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":529,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/529\/","url_meta":{"origin":593,"position":1},"title":"New Delphi Upgrade Policy &#8211; Get in QUICK!","date":"16 Sep 2009","format":false,"excerpt":"If you are using any version of Delphi that is more than 3 versions older than the current version (i.e. Delphi 2005 or older, as of today), the days of upgrading to the latest version will soon be over. I am seriously disheartened by this change in policy. Whether you\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":533,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/533\/","url_meta":{"origin":593,"position":2},"title":"Delphi: Community Edition (A Proposal)","date":"21 Sep 2009","format":false,"excerpt":"The time has come, the Walrus said, to talk of many things. \u00a0Of shoes, and ships, and sealing-wax. \u00a0Of cabbages, and kings. \u00a0And why the sea is boiling hot, and whether pigs have wings. And why the cheapest version of Delphi costs a new user as much as a pretty\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1300,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1300\/","url_meta":{"origin":593,"position":3},"title":"What&#8217;s in a Name(space) ?","date":"28 Nov 2012","format":false,"excerpt":"The ever evolving DWScript project continues to advance the Pascal language at an impressive pace. Just today it was announced that this scripting version of Pascal now has \"namespace\" support. When I first read the details of the implementation, my initial reaction was that it \"felt a bit backwards\". The\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":900,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/900\/","url_meta":{"origin":593,"position":4},"title":"Porting the Objective-C CFFTPSample to XE2: Part 1","date":"04 Jul 2012","format":false,"excerpt":"On the NZ DUG email list (yes, we still have those here) a question was recently posted asking for help with getting some FTP code working on OSX, using XE2. This coincided nicely with my reaching a point in my Objective-C learning where this sort of exercise was of interest\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":636,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/636\/","url_meta":{"origin":593,"position":5},"title":"Nick Hodges &#8220;Let Go&#8221; by Embarcadero","date":"19 Jul 2010","format":false,"excerpt":"I hadn't posted on this news before as I expected there to be a veritable deluge of opinion flooding the Delphi blog-o-sphere and didn't see any point adding to that noise, but there has been a curious silence on the matter, so here is my two-penneth after all. Nick Hodges\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/593"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=593"}],"version-history":[{"count":12,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/593\/revisions"}],"predecessor-version":[{"id":604,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/593\/revisions\/604"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=593"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=593"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=593"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}