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 4,262 other subscribers

Archive for November 18th, 2020

Checkout github pull requests locally · GitHub

Posted by jpluimers on 2020/11/18

Checkout github pull requests locally. GitHub Gist: instantly share code, notes, and snippets.

Source: [WayBack] Checkout github pull requests locally · GitHub

The trick is to add one more fetch line to the [remote "origin"] sections in your .git/config files, as in the gist below.

fetch = +refs/pull/*/head:refs/remotes/origin/pr/*

Which reminds me I should read more about that the fetch syntax which is called RefSpec: [WayBack] Git – The Refspec

–jeroen

Read the rest of this entry »

Posted in Development, DVCS - Distributed Version Control, git, GitHub, Software Development, Source Code Management | Leave a Comment »

Do not make methods protected unless you want them to be visible as public

Posted by jpluimers on 2020/11/18

One of the protection levels in Delphi is protected. Originally meant for the class itself, that level is also visible to “friends”: anything in the same unit, for example:

unit BusinessLogicUnit;

interface

type
  TBusinessLogic = class(TObject)
  protected
     Procedure Foo();
     // ...
  public
     // ...
  end;

implementation

// ...

end.

You can even access them from outside that unit by using a trick like below.

Some people use the protected section so that unit tests can assess them using the below trick.

Do not do that!

It means anyone can use that trick, often doing more damage than good.

In this case, the trick was abused by a clever programmer that was relatively new to the code base. It resulted in unintended side effects.

unit HackUnit;

interface

implementation

uses
  BusinessLogicUnit;

type
  TBusinessLogicHack = class(TBusinessLogic);

procedure Hack;
var
  Instance: TBusinessLogicHack;
begin
  Instance := TBusinessLogicHack.Create();
  try
    Instance.Foo();
  finally
    Instance.Free();
  end;
end;

end.

Of course you can still access it like below.

It is slightly longer, but more importantly: much better shows the intent and how that intent is accomplished.

unit GoodUsageUnit;

interface

implementation

uses
  BusinessLogicUnit;

type
  TBusinessLogicDescendant = class(TBusinessLogic)
  public
    procedure Foo();
  end;

procedure TBusinessLogicDescendant.Foo();
begin
  inherited Foo();
  // ...
end;

procedure Usage;
var
  Instance: TBusinessLogicDescendant;
begin
  Instance := TBusinessLogicDescendant.Create();
  try
    Instance.Foo();
  finally
    Instance.Free();
  end;
end;

end.

–jeroen

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

The Delphi Geek: Using Generics to Manipulate Enumerated Types

Posted by jpluimers on 2020/11/18

Not that this is bad code, but there are no unit tests for them, and I have seen places in the wild that blindly use it without documenting where it came from and what tested alternatives might be: [WayBack] The Delphi Geek: Using Generics to Manipulate Enumerated Types

The unit itself is down (though there is still a copy on the WayBack machine).

The post itself mentions it is Spring4D-inspired, and since Spring4D already has quite an extensive [WayBack] TEnum<T> implementation covered by unit tests, so that is a logical place to do for.

I might actually document the migration table if I find time for it.

Here is a start so I will only have to insert the blanks

Function Replacement
class function Clip(const value: Integer): T;
class function Clip(const value: T): T;
class function Ensure(const value: Integer; const min, max: T): T;
class function Ensure(const value, min, max: T): T;
class function FromInt(const value: Integer): T;
class function Enum: RangeEnum; static;
class function GetValueOrDefault(const value: Integer): T;
class function IsValid(const value: Integer): Boolean;
class function IsValid(const value: T): Boolean;
class function Max: T; static;
class function Min: T; static;
class function ToInt(const value: T): Integer;
class function ToString(const value: T): string;

–jeroen

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