The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,854 other subscribers

Archive for the ‘Delphi’ Category

How To Write Unmaintainable Code: Ensure a job for life ;-) by Roedy Green Canadian Mind Products

Posted by jpluimers on 2020/12/09

A great reference on how not to code still is

How To Write Unmaintainable Code

Ensure a job for life ;-)

Roedy Green Canadian Mind Products

I am still amazed when browsing through code, how many people use one or more of the anti-patterns in it.

One example I came across was this piece of Delphi RTL code:

class function TMarshalUnmarshalBase.ComposeKey(clazz: TClass; Field: string): string;
begin
  if clazz <> nil then
    Result := clazz.UnitName + SEP_DOT + clazz.ClassName + SEP_DOT + Field
  else
    Result := '';
end;

So I did a quick search at in the Delphi RTL for clazz, then found these occurences, indicating not only the authors of them have been under a rock, but also the code reviewers:

  • 98 in data\dbx\Data.DBXJSONReflect.pas
  • 7 in data\dbx\Data.DBXTransport.pas
  • 97 in data\rest\REST.JsonReflect.pas
  • 3 in DUnit\src\TestFramework.pas
  • 22 in indy\abstraction\IPPeerAPI.pas

I have seen similar things in many environments, even run-time libraries of others, though this is one of the worst examples and falls under the anti-pattern:

Thesaurus Surrogatisation

To break the boredom, use a thesaurus to look up as much alternate vocabulary as possible to refer to the same action, e.g. displayshowpresent. Vaguely hint there is some subtle difference, where none exists. However, if there are two similar functions that have a crucial difference, always use the same word in describing both functions (e.g. print to mean “write to a file”, “put ink on paper” and “display on the screen”). Under no circumstances, succumb to demands to write a glossary with the special purpose project vocabulary unambiguously defined. Doing so would be an unprofessional breach of the structured design principle of information hiding.

There is a great other anti-pattern in the document too:

Delphi/Pascal Only

: Don’t use functions and procedures. Use the label/goto statements then jump around a lot inside your code using this. It’ll drive ’em mad trying to trace through this. Another idea, is just to use this for the hang of it and scramble your code up jumping to and fro in some haphazard fashion.

Enjoy reading the anti-pattern descriptions, which are now maintained at [WayBack] GitHub – Droogans/unmaintainable-code: A more maintainable, easier to share version of the infamous http://mindprod.com/jgloss/unmain.html, as it was originally a multi-page hard to maintain set of small articles:

A lot of comments were posted because of it: [WayBack] Responses to Roedy’s Unmaintainable Code Essay

Via:

–jeroen

Posted in .NET, Delphi, Development, Software Development | 1 Comment »

Delphi and SuperObject JSON support have a very different implementation

Posted by jpluimers on 2020/12/09

In the comments of [WayBack] Delphi and JSON Is there an overlay (eg in the form of a helper) for the JSON classes built into Delphi (System.JSON), which offered an interface simil… – Jacek Laskowski – Google+

SuperObject has a very different implementation for JSON support than the Delphi RTL System.JSON unit as explained by Dalija Prasnikar:

If you are thinking about replacing existing code that uses SuperObject with Delphi build in JSON library, you have another problem on desktop – non-ARC compiler. SuperObject classes are interface based (reference counted) and Delphi JSON is class based – non ref-counted.

These methods are not in the Delphi RTL because of the difference:

How to read a property value of an object ?

  val := obj.AsObject.S['foo']; // get a string
  val := obj.AsObject.I['foo']; // get an Int64
  val := obj.AsObject.B['foo']; // get a Boolean
  val := obj.AsObject.D['foo']; // get a Double
  val := obj.AsObject.O['foo']; // get an Object (default)
  val := obj.AsObject.M['foo']; // get a Method
  val := obj.AsObject.N['foo']; // get a null object

How to read a value from an array ?

  // the advanced way
  val := obj.AsArray.S[0]; // get a string
  val := obj.AsArray.I[0]; // get an Int64
  val := obj.AsArray.B[0]; // get a Boolean
  val := obj.AsArray.D[0]; // get a Double
  val := obj.AsArray.O[0]; // get an Object (default)
  val := obj.AsArray.M[0]; // get a Method
  val := obj.AsArray.N[0]; // get a null object

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

delphi “tproc” with “array of const” – Google Search

Posted by jpluimers on 2020/12/08

Reminder to self: remember which of the open source libraries have:

  • a generic TProc<T> alike with an const values: array of const T parameter
  • a generic TProc<T> alike with a const value: T parameter

Google returned none that stuck:

The Delphi RTL does not contain them, and because they forgot setting them up with const parameters, these can never be changed:

[WayBack] System.SysUtils.TProc – RAD Studio API Documentation

TProc = reference to procedure;
TProc<T> = reference to procedure (Arg1: T);
TProc<T1,T2> = reference to procedure (Arg1: T1; Arg2: T2);
TProc<T1,T2,T3> = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3);
TProc<T1,T2,T3,T4> = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3; Arg4: T4);

More people are annoyed by this, for instance [WayBack] SysUtils.pas Why parameters of these anonymous not const? TProc = reference to procedure (Arg1: T1; Arg2: T2); TProc = reference … – Jacek Laskowski – Google+

SysUtils.pas

Why parameters of these anonymous not const?

TProc<T1,T2> = reference to procedure (Arg1: T1; Arg2: T2);
TProc<T1,T2,T3> = reference to procedure (Arg1: T1; Arg2: T2; Arg3: T3);
TFunc<T,TResult> = reference to function (Arg1: T): TResult;
TFunc<T1,T2,TResult> = reference to function (Arg1: T1; Arg2: T2): TResult;

  • David Heffernan's profile photo
    Because the designer made a bloody terrible mistake 
  • Asbjørn Heid's profile photo
    To be fair, const-ness is a bloody mess in Delphi…
  • Hallvard Vassbotn's profile photo
    It could have been solved if the const’ness had been seen as a implementation detail by the compiler (which it really is) and made const and non-const signatures assignment compatible.
  • David Heffernan's profile photo
    +Hallvard Vassbotn indeed, and it pains me that this has never happened
  • Hallvard Vassbotn's profile photo
    +Marco Cantu Any chance of a compiler improvement in the future with regards to relaxing const matching in signature assignments…? :)
  • Vincent Parrett's profile photo
    I’ve taken to defining
    TConstProc<T1,T2> = reference to procedure (const Arg1: T1; const Arg2: T2);for cases where I have full control.

  • David Heffernan's profile photo
    +Vincent Parrett I’m sure we all have our own versions of this. But it’s not much use for composition of course.
  • Vincent Parrett's profile photo
    +David Heffernan Yup. Since it’s unlikely the compiler will every be updated to make const an automatic thing, perhaps they could add const versions to the RTL.
  • Allen Drennan's profile photo
    Yeah, we end up making our own versions of these to add the consts in all our projects.
  • David Millington's profile photo
    Do file a QP, please. Major releases like the upcoming 10.3 are the time to make interface-breaking changes.

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

.NET: interfaces that inherit from multiple base interfaces

Posted by jpluimers on 2020/12/03

For my link archive:

Read the rest of this entry »

Posted in .NET, C#, Delphi, Development, Software Development | Leave a Comment »

I’m using Delphi XE 10.2: empty documentation tab means you need to update to either the documentation Hotfix or 10.2.3

Posted by jpluimers on 2020/12/03

If you see the Documentation tab like below you need to either:

The problem is caused by Embarcadero using mixed technologies in the Delphi IDE combined with their lack of testing due to not eating their own dog-food.

Too bad, as the documentation over the last versions has finally increased after a 10+ year steady decline.

Doing one technology right is hard, but having to mix multiple technologies into one product is extremely hard.

Via: [WayBack] I’m using Delphi XE 10.2. Whenever I click on the Documentation tab, I see the following uselessly rendered page. I can’t seem to resize it either. Anyb… – Graeme Geldenhuys – Google+

–jeroen

Read the rest of this entry »

Posted in Delphi, Delphi 10.2 Tokyo (Godzilla), Development, Software Development | Leave a Comment »

Delphi spring collections

Posted by jpluimers on 2020/12/02

[WayBack] Spring Collections I have a list of elements, there are, for example, 100 of them. List : IList; I want to get 5 values greater than 10 and … – Jacek Laskowski – Google+

Q

I have a list of elements, there are, for example, 100 of them.

List : IList<Integer>;

I want to get 5 values greater than 10 and I do it like this:

result: = List.Where(ValueIsGreatThan10).Take(5);

Will the “work loop” be executed a minimum number of times and if, for example, the first 5 values in the list will be greater than 5, then only the five will be checked? Or maybe the Where() loop will scan 100 elements, and Take() will return the first 5 results?

A (by Stefan Glienke)

Where and Take are streaming operators and only execute as much as required.

Also the operations have deferred execution. So your statement does not materialize any collection yet. Only if you iterate it will.

They are designed after the operators in .NET so the table from [WayBack] Classification of Standard Query Operators by Manner of Execution (C#) | Microsoft Docs applies. If you find any difference please report it.

Example:

var
  nums: IEnumerable<Integer>;
  i: Integer;
begin
  nums := TEnumerable.Range(1, 100).Where(
    function(const i: Integer): Boolean
    begin
      Writeln('checking: ', i);
      Result := i > 10;
    end
  ).Take(5);
  Writeln('query created');
  for i in nums do
    Writeln('got number: ', i);
end.

This code will print:

query created
checking: 1
checking: 2
checking: 3
checking: 4
checking: 5
checking: 6
checking: 7
checking: 8
checking: 9
checking: 10
checking: 11
got number: 11
checking: 12
got number: 12
checking: 13
got number: 13
checking: 14
got number: 14
checking: 15
got number: 15

–jeroen

Posted in .NET, Delphi, Development, Software Development | Leave a Comment »

Delphi Compiler Intrinsics can help you collapse generated code for generics a lot

Posted by jpluimers on 2020/12/01

On my reading list [WayBack] Delphi Corner Weblog: The current state of generics in Delphi because it explains in more detail why Delphi compiler generic type based intrinsics introduced some 5 years ago, but never been (accurately) documented, but listed at [WayBack] delphi – Undocumented intrinsic routines – Stack Overflow, are so important to help collapse decreasing code bloat:

  • Default
  • IsManagedType
  • HasWeakRef
  • GetTypeKind

There is also the TypeInfo which is somewhat documented on-line starting in the Delphi 2007 documentation:

 

And some non-generic intrinsics that are still undocumented:

  • IsConstValue
  • ReturnAddress

Spring4D already has been making use of this for a few years, and you can too!

Via [WayBack] rvelthuis.blogspot.com/2018/10/the-current-state-of-generics-in-delphi.html – Jacek Laskowski – Google+ that has some more information on Spring4D too.

A tiny bit more information on collapsing: [WayBack] TURBU Tech » Blog Archive » Wish list: Generics collapsing

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Delphi revelations #3 – kbmMW Smart client – DispInvoke leak – Components4Developers

Posted by jpluimers on 2020/11/26

For my archive, as one day I will run into this Variant/DispInvoke issue myself:[WayBack] Delphi revelations #3 – kbmMW Smart client – DispInvoke leak – Components4Developers:

Delphi revelations, now about investigating a pesky DispInvoke bug in all versions of Delphi supported by kbmMW, including 10.3 Rio, that results in leaks, and how kbmMW now ends up not being affected by it.

Via: [WayBack] Next Delphi revelations, now about investigating a pesky DispInvoke bug in all versions of Delphi supported by kbmMW, including 10.3 Rio, that results i… – Kim Madsen – Google+

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Delphi: why breakpoints from time to time are not usable (green highlighted line on IDE)? – Stack Overflow

Posted by jpluimers on 2020/11/25

I still have not figured out the circumstances, but ever since either the Unicode Delphi versions (2009 and up) or BDS (8 and up), I have this every now and then: [WayBack] Delphi: why breakpoints from time to time are not usable (green highlighted line on IDE)? – Stack Overflow

So far this is consistent, limiting it to:

  • large projects (100+ kilo-lines-of-code)
  • for those projects, either as single .dproj file or as part of a .groupproj
  • debugging works the first time, but fails consistently with these symptoms:
    • break-points fail
    • blue dots in the gutter disappear; red-dots become green
    • exceptions cause a stack-trace with only hex-addresses
  • other projects in the same project group still debug fine

To get it working (one time per try) again:

  • restart the IDE
  • close the project, then re-open it in the same IDE instance

What does not help getting it to work:

  • clean build from the IDE
  • deleting DCU files

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

A bunch of Spring4D dependency injection container related questions

Posted by jpluimers on 2020/11/19

Since G+ is down, a lot of interesting questions have vanished.

Luckily I saved some by [WayBack] Jacek Laskowski – Google+ related to Spring4D and dependency injection:

[WayBack] Spring4D IoC and specific singleton… – Jacek Laskowski – Google+

First my Google Groups archival reminder:

  1. Rename from
  2. To
  3. Save that URL with Archive.is

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »