The Wiert Corner – irregular stream of stuff

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

  • My badges

  • Twitter Updates

  • 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

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 »

GitHub – DevExpress/testcafe: A Node.js tool to automate end-to-end web testing.

Posted by jpluimers on 2020/12/09

In my list of things to play with: [WayBack] GitHub – DevExpress/testcafe: A Node.js tool to automate end-to-end web testing.:

A Node.js tool to automate end-to-end web testing.
Write tests in JS or TypeScript, run them and view results.

https://devexpress.github.io/testcafe


  • Works on all popular environments: TestCafe runs on Windows, MacOS, and Linux. It supports desktop, mobile, remote and cloud browsers (UI or headless).
  • 1 minute to set up: You do not need WebDriver or any other testing software. Install TestCafe with one command, and you are ready to test: npm install -g testcafe
  • Free and open source: TestCafe is free to use under the MIT licensePlugins provide custom reports, integration with other tools, launching tests from IDE, etc. You can use the plugins made by the GitHub community or make your own.

Related:

  • [WayBack] A node.js tool to automate end-to-end web testing | TestCafe:

    Use TestCafe to write tests in JS or TypeScript, run them and view results. TestCafe runs on Windows, MacOS, and Linux and takes 1 minute to set up.

  • [WayBack] TestCafe: Web Testing Framework | DevExpress

    100% web-based functional testing framework with integrated visual test recorder, remote device testing, and natural JavaScript API

    • From download to recording your first test in less than 5 minutes — installer automatically configures your environment.
    • With TestCafe, you can run tests in any browser that supports HTML5 (including IE9+, Chrome, Firefox, Safari, Opera).
    • TestCafe is operating system agnostic so you can run tests on Windows, Mac or Linux machines.
    • Run tests on remote computers and mobile devices.
    • Run tests in multiple browsers and on multiple machines in parallel.
    • Run tests in the background on any machine.
    • TestCafe allows you to test web pages that require Basic and Windows HTTP Authentication.

Via:

Screen materials below the fold.

–jeroen

Read the rest of this entry »

Posted in Development, JavaScript/ECMAScript, LifeHacker, Power User, Scripting, Software Development, Testing, Web Development | Leave a 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 »

Tables with two headers • Tables • WAI Web Accessibility Tutorials

Posted by jpluimers on 2020/12/08

Since I always forget that you can have any cell marked as th to make it a header: [WayBack] Tables with two headers • Tables • WAI Web Accessibility Tutorials.

This is not just limited to top rows, you can use it any where:

  • in the left column
  • in any other row
  • in any other column
  • in individual cells

In addition, a table can also have a caption, which is not just useful for screen-readers: it benefits general readability.

Quoting the page:

For such tables, use the <th> element to identify the header cells and the scope attribute to declare the direction of each header. The scopeattribute can be set to row or col to denote that a header applies to the entire row or column, respectively.

Additionally, you can use the <caption> element to identify the table in a document. This is particularly useful for screen-reader users browsing the web page in “table mode” where they can navigate from table to table.

Examples on that page:

–jeroen

Posted in Development, HTML, HTML5, Software Development, Web Development | Leave a Comment »

WSA: Web-Service Addressing

Posted by jpluimers on 2020/12/08

I don’t do SOAP that often any more, so here some links on it and some notes on how one site used some of the fields:

A few observations from real life:

  • Inside the WS-Addressing realm:
    • Action has a URI indicating what to execute inside the service
    • From is basically abused because it
      1. is not used as a source endpoint but
      2. has an Address element that contains both Action and authentication
    • MessageID uses a uuid: based URI
  • Outside the WS-Addressing realm, in the main SOAP body:
    • Since is implemented using a non ISO-8601 compliant timestamp: it barfs on the second fraction and on the time zone (neither Z nor an offset based time-zone are accepted).

I did not know you could have uuid based URIs, as they are not mentioned here:

But apparently they have been in use for quite a while:

–jeroen

Posted in Development, SOAP/WebServices, Software Development, XML, XML/XSD | 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 »

Lifehack: solving jigsaw puzzles on whiteboards

Posted by jpluimers on 2020/12/07

I was a bit amazed that “lifehack” “jigsaw puzzle” “whiteboard” – Google Search returned zero meaningful results.

I got at this “lifehack” via two different paths.

The first one had been simmering in my head because my mentally retarded brother has periods where he loves solving jigsaw puzzles, and periods he does not.

A while ago, he (and being his custodians: we too) had a few rough years that took us a while to help alleviate. There were a lot of symptoms, like anxiety, mixing fantasy and real life, much shortened attention span, mix-ups of both short-term and long-term memory, and a lot more. His life structure was falling apart, which resulted in a lot of puzzles to be started and abandoned shortly after.

It put a lot of pressure on us, which meant my idea of trying to “store” his unfinished puzzles somewhere never took form.

The second one came when towards the end of that period, he got back into a jigsaw puzzle solving period. But this time, he could retain solving focus for a few days in a row.

I tweeted about that in Dutch, showing my amazement. But he was still not back his former level of solving, nor level of understanding.

So close to the Christmas days, he got himself a duo-jigsaw puzzle: two 1000 pieces puzzles in one box. Not being aware of the consequences, he opened both plastic bags and put them in the box.

Back in the days (almost a “Once upon a time…“) quality puzzles had pieces with smooth backs, usually printed in one colour per puzzles. Those times are over, we live in a mass production world, where every penny – or less – is shaved off in a drip-feed method like way, meaning the backs are just roughened cardboard all in one colour.

So we needed to find a way to solve two puzzles at the same time, including a place to store them when he was not staying with us.

He had been using puzzle mats, which all have drawbacks, some of which are in the video below, including:

  • pieces get damaged
  • sticking mat material sticks dust even better than puzzle pieces
  • mats usually come folded and take ages for the fold to disappear
  • inflatable tubes deflate over time because their plastic is porus
  • elastic straps are too cheap for their elasticity to last
  • cannot be used on flat areas smaller than the mat

Basically I needed portable large flat areas with slightly raised edges.

While showering – always a great time to get ideas – it occurred to me: magnetic whiteboards are flat, had raised edges, relatively sturdy, portable, thin, easy to store (because stackable).

Being magnetic makes it easy to stick a cotton cloth (say a large bed pillow case) to top or bottom so they would not scratch the underlying table, or to protect the puzzle from dust.

I choose a 90×60 cm whiteboard, which Amazon.de does not deliver to The Netherlands, but Amazon might deliver it to yours:

So I got a set of these: [WayBack] bol.com | Whiteboard Magneetbord 60x90cm which was EUR 27 back then, but immediately rose to EUR 28+ after buying (:

Related tweets

The last tweet is my brother after having spent like 40 hours on this 750 piece Ravensburger “bergbauernhof” puzzle over a couple of months, now spent 2 days in a row puzzling and making way more progress than the first 25+ hours. He was proud, and we were too, as this was the first time in about 2 years he could focus on such things for such a long time in a row.

The first tweet is on him getting a Jan van Haasteren 19083 set of two 1000 piece puzzles without him realising there are two:

Read the rest of this entry »

Posted in LifeHacker, Power User | Leave a Comment »

Running BBS Door Games on Windows 10 with GameSrv, DOSBox, plus telnet fun with WSL – Scott Hanselman

Posted by jpluimers on 2020/12/07

Reminder to self: see if I ever can resurrect my old BBS and FidoNet node that was based on at least:

  • FrontDoor (by Joaquim Homrighausen)
  • RemoteAccess (by Andrew Milner)
  • GoldED (by Odinn Sørensen)
  • A FOSSIL driver (forgot the name)
  • A Fidonet NodeList Compiler
  • a Message Tosser

Maybe a good place to start: [WayBack] Running BBS Door Games on Windows 10 with GameSrv, DOSBox, plus telnet fun with WSL – Scott Hanselman

I already wrote a few times about me being on Fidonet, and BITNET in the late 1980s:

A few email addresses I have been using in that era:

A tag-line from me in that era (I blanked out the phone number as it now belongs to someone else):

    o _   _  _   _   _             voice:  +31-2522-XXXXX (19:00-22:00 UTC)
   / (_' |  (_) (_' | |            snail:  P.S.O.
__/                                        attn. Jeroen W. Pluimers
                                           P.O. Box 266
jeroenp@rulfc1.LeidenUniv.nl               2170 AG Sassenheim
jeroen_pluimers@f521.n281.z2.fidonet.org   The Netherlands

Related:

–jeroen

Posted in BBS, dial-up modems, FidoNet, History, MS-DOS, Power User, Windows | Leave a Comment »

HMpaal.nl: exacte (Google maps) locatie van een hectometerpaal op een A of N weg

Posted by jpluimers on 2020/12/07

Handig: [WayBack] HMpaal.nl.

Behoorlijk exact (veel exacter dan andere bronnen) voor locaties van hectometerpalen langs A en N wegen die door rijkswaterstaat beheerd worden.

Zie ook:

Voorbeeld:

[WayBack/Archive.is] HMpaal.nl A9/R/36.9/a 

–jeroen

Posted in LifeHacker, Power User | Leave a Comment »

gpg creation and sign Gino’s Key ($1785651) · Snippets · GitLab

Posted by jpluimers on 2020/12/04

Boy it was a long time ago that I did anything with gpg. Here is how to generate and sign keys.

[WayBack] gpg creation and sign Gino’s Key ($1785651) · Snippets · GitLab

And here to check your email confguration:

[WayBack] Home – dmarcian Founded in 2012 by the primary author of the DMARC specification, dmarcian is dedicated to upgrading the entire world’s email by making DMARC accessible to all. dmarcian brings together thousands of senders, vendors, and operators in a common effort to build DMARC into the email ecosystem.

–jeroen

Posted in *nix, Power User, Security | Leave a Comment »