<?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-1207941472577020982</id><updated>2011-04-22T02:29:57.570+02:00</updated><category term='Coding'/><category term='Delphi.NET'/><title type='text'>If at first you don't succeed...</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jonashogstrom.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1207941472577020982/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jonashogstrom.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jonas Hogstrom</name><uri>http://www.blogger.com/profile/14446248078283464928</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-1207941472577020982.post-3061502117891907838</id><published>2008-02-15T11:29:00.006+01:00</published><updated>2008-02-18T12:03:28.950+01:00</updated><title type='text'>The art of writing a good bugreport</title><content type='html'>if at first you don't succeed... file a bugreport&lt;br /&gt;&lt;br /&gt;Over the years I've seen quite a number of bug reports, and often they were inspired by a bug, and often enough, the bug was mine to fix.&lt;br /&gt;&lt;br /&gt;In order to fix a bug, a developer needs a good bug report. The classic case of a bad bug report that we have used for a long time now in the eco team is the "kaboom" bug report.&lt;br /&gt;The customer simply said: "I tried to do this and that and 'kaboom'!"... how were we supposed to interpret that? did the machine really explode?&lt;br /&gt;&lt;br /&gt;Here are a few things to think about when you report a bug to someone else:&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Reproducible:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Make sure you can reproduce the bug. Make sure you know the required starting point and the exact steps to make the bug appear. If you don't know these things, at least be honest about it, and preferably, find a good discussion forum to ventilate your problem and see if anyone else knows the steps to reproduce the issue before reporting it.&lt;br /&gt;In some cases, it could be enough with just an exception message and a callstack to be able to fix the bug, but it is hard to know if the bug is really fixed if it can't be reproduced.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Steps:&lt;/span&gt;&lt;br /&gt;If your bug is reproducible, then you know the steps to reproduce it. The developer responsible for fixing the bug hasn't seen the bug happen when he reads the report. He (or she) will need detailed steps in order to reproduce the bug.&lt;br /&gt;Ideally, the steps looks something like&lt;br /&gt;* New winform eco project&lt;br /&gt;* add a class with an attribute of type X&lt;br /&gt;* generate source&lt;br /&gt;* Drop a button on the form, execute: &lt;some&gt;&lt;br /&gt;Exp: this&lt;br /&gt;Act: that&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Exp and Act&lt;/span&gt;&lt;br /&gt;It is very important to explain both what actually happens (act9, and what you expected to happen (exp). Sometimes, maybe your expectation is wrong, and what really needs fixing is the documentation so that you know what to expect. In order for the developer to know that he has reproduced your bug he needs to know what happens in your environment.&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;Isolate the bug:&lt;/span&gt;&lt;br /&gt;The fewer steps needed to expose the bug, the better. Try to eliminate as much noise as possible. If you are using third party components, try to reproduce the bug without those. If the bug doesn't seem to be related to persistence, try to reproduce the issue in a transient system.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Sample project:&lt;/span&gt;&lt;br /&gt;In many cases, a small example project that exhibits the bug can be helpful, but sending your 100kloc project with a 3gb sqlserver database is usually not appreciated. Also, when you attach a testcase to your bugreport, please remove any compiled files unless you are certain they are needed to reproduce the bug. Zip up your project and then remove the following:&lt;br /&gt;*.exe; *.dll; *.pdb; *.dc?il; *.identcache; bin-dir, obj-dir, any history/backup files.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Exceptions and Callstacks:&lt;/span&gt;&lt;br /&gt;Callstacks are often very helpful for a developer to figure out what is wrong. The exact error message in the exception is also very important. Please include these if you get an exception.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Unit tests:&lt;/span&gt;&lt;br /&gt;I have been thinking of writing this piece for many years, and I had always planned to add a contest at the end. The first person who would submit a previously unknown bug with an accompanying unittest that exposed the bug would win a beer. I had never seen this in any of the bug reports I have received in the past 10 years as a developer until Dmitriy Nagirnyak sent me a bugreport last october (http://magpie.sytes.net/mantis/view.php?id=237). Read and learn folks! It was a fairly complicated bug, but Dmitriy had done his homework and isolated the bug, prepared a testcase and explained all the details required to understand the bug. Instead of promising a beer to the winner (Dmitriy, whenever we meet the beer is on me), I promise a private build off the current stable branch of eco if you submit a new bug with a relevant isolated nunit-testcase as soon as the fix has been checked in.&lt;br /&gt;&lt;br /&gt;So... if you find a bug, don't be afraid to report it, but please follow these guidelines when you do.&lt;br /&gt;&lt;/some&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207941472577020982-3061502117891907838?l=jonashogstrom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jonashogstrom.blogspot.com/feeds/3061502117891907838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1207941472577020982&amp;postID=3061502117891907838' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1207941472577020982/posts/default/3061502117891907838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1207941472577020982/posts/default/3061502117891907838'/><link rel='alternate' type='text/html' href='http://jonashogstrom.blogspot.com/2008/02/file-bugreport.html' title='The art of writing a good bugreport'/><author><name>Jonas Hogstrom</name><uri>http://www.blogger.com/profile/14446248078283464928</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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1207941472577020982.post-582725412168284847</id><published>2008-01-31T14:10:00.000+01:00</published><updated>2008-01-31T14:24:20.677+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Coding'/><title type='text'>Dynamic instantiation of generic types</title><content type='html'>&lt;span style="font-family:arial;"&gt;If at first you don't succeed...Change the rules.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Once I had managed to create the implementation of IList[T] (see &lt;a href="http://jonashogstrom.blogspot.com/2008/01/implementing-generic-ilist-in-delphinet.html"&gt;last post&lt;/a&gt;), I was faced with the problem of instantiating it dynamically. All I had was the type and a reference to the type that I wanted to substitute for T. The argument to the generic type was not fixed statically.&lt;br /&gt;&lt;br /&gt;I tried to get System.Type.GetType(string s) to return the type:&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;  System.Type.GetType(&lt;br /&gt;  'MyNameSpace.MyGenericType`1[MyOtherNameSpace.MyOtherType]');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;but it simply didn't want to return my type. I finally settled for this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Type arg = (* expression that resulted in a type reference *)&lt;br /&gt;object temp = new MyGenericType[object]();&lt;br /&gt;Type t = temp.GetType.&lt;br /&gt;  GetGenericTypeDefinition.MakeGenericType(new Type[]{arg});&lt;br /&gt;object newObj = Activator.CreateInstance(&lt;br /&gt;  t,&lt;br /&gt;  new object[]{ (* constructor parameters *)} );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Anyone know a way around the Activator class to improve performance?&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207941472577020982-582725412168284847?l=jonashogstrom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jonashogstrom.blogspot.com/feeds/582725412168284847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1207941472577020982&amp;postID=582725412168284847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1207941472577020982/posts/default/582725412168284847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1207941472577020982/posts/default/582725412168284847'/><link rel='alternate' type='text/html' href='http://jonashogstrom.blogspot.com/2008/01/dynamic-instantiation-of-generic-types.html' title='Dynamic instantiation of generic types'/><author><name>Jonas Hogstrom</name><uri>http://www.blogger.com/profile/14446248078283464928</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-1207941472577020982.post-3313336782752356579</id><published>2008-01-31T08:17:00.000+01:00</published><updated>2008-01-31T14:09:03.057+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Delphi.NET'/><title type='text'>Implementing generic IList in Delphi.NET</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;If at first you don't succeed... hide your astonishment&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Last night I had to implement the generic version of IList in delphi. It turned out to be a little more tricky than I had hoped... The compiler didn't always give the most helpful error messages. Anyway, here is a minimal implementation of System.Collections.Generic.IList[T] in Delphi.NET (including a custom enumerator). Just replace all square brackets with the angle brackets (couldn't figure out how to get blogger to show them).&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre class="sourcecode"&gt;&lt;code&gt;&lt;b&gt;type&lt;/b&gt;&lt;br /&gt;TMyListImpl[T] = &lt;b&gt;class&lt;/b&gt;(TObject, IList, &lt;br /&gt;    ICollection, ICollection[T], IList[T])&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; IList.GetEnumerator = IList_GetEnumerator;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; IList.get_Item = IList_get_Item;&lt;br /&gt;&lt;b&gt;public&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; IList_GetEnumerator: IEnumerator;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; GetEnumerator: IEnumerator[T];&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; CopyTo(arr: System.&lt;b&gt;Array&lt;/b&gt;; &lt;b&gt;index&lt;/b&gt;: integer); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; CopyTo(arr: &lt;b&gt;array&lt;/b&gt; &lt;b&gt;of&lt;/b&gt; T; &lt;b&gt;index&lt;/b&gt;: integer); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; get_SyncRoot: System.&lt;b&gt;Object&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; get_IsSynchronized: Boolean;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; get_Count: integer;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; Add(value: T); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; Add(value: TObject): integer; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; ICollection_Add(value: TObject): integer;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; Clear;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; &lt;b&gt;Contains&lt;/b&gt;(value: T): boolean; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; &lt;b&gt;Contains&lt;/b&gt;(value: TObject): boolean; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; IndexOf(value: T): integer; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; IndexOf(value: TObject): integer; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; Insert(&lt;b&gt;index&lt;/b&gt;: integer; value: T); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; Insert(&lt;b&gt;index&lt;/b&gt;: integer; value: TObject); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; Remove(value: T): Boolean; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; Remove(value: TObject); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; RemoveAt(&lt;b&gt;index&lt;/b&gt;: integer);&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; get_IsFixedSize: Boolean;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; get_IsReadOnly: Boolean;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; get_Item(&lt;b&gt;index&lt;/b&gt;: integer): T; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; set_Item(&lt;b&gt;index&lt;/b&gt;: integer; Value: T); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; IList_get_Item(&lt;b&gt;index&lt;/b&gt;: integer): TObject; &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; set_Item(&lt;b&gt;index&lt;/b&gt;: integer; Value: TObject); &lt;b&gt;overload&lt;/b&gt;;&lt;br /&gt;  &lt;b&gt;property&lt;/b&gt; Item[&lt;b&gt;index&lt;/b&gt;: integer]: T &lt;b&gt;read&lt;/b&gt; get_Item &lt;b&gt;write&lt;/b&gt; set_Item;&lt;br /&gt;  &lt;b&gt;property&lt;/b&gt; IsReadOnly: Boolean &lt;b&gt;read&lt;/b&gt; get_IsReadOnly;&lt;br /&gt;  &lt;b&gt;property&lt;/b&gt; IsFixedSize: Boolean &lt;b&gt;read&lt;/b&gt; get_IsFixedSize;&lt;br /&gt;  &lt;b&gt;property&lt;/b&gt; Count: integer &lt;b&gt;read&lt;/b&gt; get_Count;&lt;br /&gt;  &lt;b&gt;property&lt;/b&gt; SyncRoot: System.&lt;b&gt;Object&lt;/b&gt; &lt;b&gt;read&lt;/b&gt; get_SyncRoot;&lt;br /&gt;  &lt;b&gt;property&lt;/b&gt; IsSynchronized: Boolean &lt;b&gt;read&lt;/b&gt; get_IsSynchronized;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;TListEnumerator[T] = &lt;b&gt;class&lt;/b&gt;(System.&lt;b&gt;Object&lt;/b&gt;, &lt;br /&gt;    IEnumerator, IEnumerator[T])&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; IEnumerator.get_Current = IEnumerator_get_Current;&lt;br /&gt;strict &lt;b&gt;private&lt;/b&gt;&lt;br /&gt;  fList: TMyListImpl[T];&lt;br /&gt;  FCurrentIndex: integer;&lt;br /&gt;&lt;b&gt;public&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;constructor&lt;/b&gt; Create(list: TMyListImpl[T]);&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; get_Current: T;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; IEnumerator_get_Current: TObject;&lt;br /&gt;  &lt;b&gt;function&lt;/b&gt; MoveNext: Boolean;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; Dispose;&lt;br /&gt;  &lt;b&gt;procedure&lt;/b&gt; Reset;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1207941472577020982-3313336782752356579?l=jonashogstrom.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jonashogstrom.blogspot.com/feeds/3313336782752356579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1207941472577020982&amp;postID=3313336782752356579' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1207941472577020982/posts/default/3313336782752356579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1207941472577020982/posts/default/3313336782752356579'/><link rel='alternate' type='text/html' href='http://jonashogstrom.blogspot.com/2008/01/implementing-generic-ilist-in-delphinet.html' title='Implementing generic IList in Delphi.NET'/><author><name>Jonas Hogstrom</name><uri>http://www.blogger.com/profile/14446248078283464928</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>
