Execute Delphi News

L'actualité Delphi par http://www.execute.fr RSS « Avant

Portage de Windows vers Linux et les dates

Publié le 15/02/2021
après mes problèmes d'accents, voici les problèmes de dates :)

si mes serveurs Windows sont généralement en français, ce n'est pas le cas du serveur Linux sur lequel j'ai déployé ma solution.

les fonctions de conversion Date/String posent alors des problèmes que l'on solutionne assez facilement finalement !

{$IFDEF LINUX}
  FormatSettings := TFormatSettings.Create('fr-FR');
{$ENDIF}


bon ok, ça serait plus propre de gérer les dates sans dépendre de FormatSettings...mais c'est une solution rapide au problème.

Portage de Windows vers Linux et les accents

Publié le 22/01/2021
Je le note ici pour m'en souvenir.

j'ai porté une application Windows sous Linux (toujours sous Delphi) et je rencontre des problèmes d'accents sur les AnsiString...cela vient de ce que la page de code par défaut de Linux n'est pas la même que celle de Windows (pour un Windows français en tout cas). Pour assurer une meilleur comptabilité, il est possible de fixer la page de code par défaut.

{$IFDEF LINUX}
  SetMultiByteConversionCodePage(1252); // https://fr.wikipedia.org/wiki/Windows-1252
{$ENDIF}


Voilà !

Utilisation des Records Managés sous Delphi Sydney

Publié le 11/08/2020
Une des grosses nouveauté de Sydney au niveau du compilateur est le support des Records Managés.

Cette fonctionnalité est assez intéressante dans son fonctionnement, elle permet d'appeler une fonction automatiquement pour initialiser un Record et une autre pour faire le ménage.

Prenons un exemple simple.
procedure TForm1.Button1Click(Sender: TObject);
var
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    SL.Add('Hello');
    SL.Add('World');
    ShowMessage(SL.Text);
  finally
    SL.Free;
  end;
end;

dans cet exemple classique (et bidon) j'instancie un StringList qui est détruit à la fin de la procédure...mais voici comment éviter le try/finally/end
type
  TStringListRecord = record
    SL: TStringList;
    class operator Initialize(out R: TStringListRecord);
    class operator Finalize(var R: TStringListRecord);
  end;

class operator TStringListRecord.Initialize(out R: TStringListRecord);
begin
  R.SL := TStringList.Create;
end;

class operator TStringListRecord.Finalize(var R: TStringListRecord);
begin
  R.SL.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  R: TStringListRecord;
begin
  R.SL.Add('Hello');
  R.SL.Add('World');
  ShowMessage(R.SL.Text);
end;

et voilà ! grâce aux deux opérateurs déclarés, TStringListRecord instancie automatiquement un TStringList qui est libéré en fin de procédure car la variable R est locale.

Alors évidemment ça n'a d'intérêt que si vous utiliser (TStringListRecord) à différents endroits, mais ce n'est qu'un exemple...et on peut aussi imager utiliser un <generic> pour faire des choses plus évoluées.
type
  TRecord<T:class,constructor> = record
    Instance: T;
    class operator Initialize(out R: TRecord);
    class operator Finalize(var R: TRecord);
  end;

class operator TRecord<T>.Initialize(out R: TRecord);
begin
  R.Instance := T.Create;
end;

class operator TRecord<T>.Finalize(var R: TRecord);
begin
  R.Instance.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  R: TRecord<TStringList>;
begin
  R.Instance.Add('Hello');
  R.Instance.Add('World');
  ShowMessage(R.Instance.Text);
end;

Pourquoi je n'aime pas les overloads

Publié le 06/12/2019
Je n'ai jamais aimé la possibilité de créer plusieurs fonctions portant le même nom mais avec différents paramètres (overload).

Je viens de taper un code utilisant les RTTI qui exprime bien en quoi cela rend les choses ambiguës

begin
  case TypeInfo.Kind of
    tkInteger: Result := IntToStr(TypeInfo.GetOrd(Instance));
    tkInt64  : Result := IntToStr(PInt64(Instance)^);
  end;
end;


On a ici un code qui cherche à déterminer le type d'une variable pour appeler dans les deux cas la fonction IntToStr()...sauf que dans le premier cas c'est un Integer et dans le second un Int64, ce n'est donc PAS la même fonction qui est invoquée !

function IntToStr(Value: Integer): string; overload;
function IntToStr(Value: Int64): string; overload;


j'aurais préféré deux fonctions distinctes

function IntToStr(Value: Integer): string;
function Int64ToStr(Value: Int64): string;


voir, éventuellement

function IntToStr(Value: Integer): string; inline; // appelle Int32ToStr()
function Int32ToStr(Value: Int64): string;
function Int64ToStr(Value: Int64): string;

ARC est mort, vive Rio 10.3

Publié le 26/10/2018
Marco en parle, c'est donc officiel, Embarcadero abandonne progressivement la gestion de la mémoire via ARC (Comptage de Référence Automatique)

je viens de traduire l'article de Marco.