喫茶XRAYトップページ


[11191] レコードヘルパー(と言うのかな?)が面白い返信 削除
2017/5/27 (土) 07:08:26 Konnoya
いつもお世話になっております。
最近、便利すぎるヘルパーにハマっています(笑)
何を今更…と言われるかも知れませんが、
案外この便利さを知らない方もいるかと思いまして投稿しました。


【Unit2】HogeIntヘルパーユニット

unit Unit2;

interface

uses
  System.SysUtils;

type
  // 別なInteger型を作る
  HogeInt = type Integer;

  // 別なInteger型のメソッドを宣言する
  HogeIntHelper = record Helper for HogeInt
  public
     // クリア
     procedure Clear;          overload; inline;
     // インクリメント
     function  Inc : HogeInt;  overload; inline;
  end;

implementation

// HogeIntクリア
procedure HogeIntHelper.Clear;

begin
  // Selfは自分自身の実体です。
  Self := 0;
end;

// インクリメント
function  HogeIntHelper.Inc : HogeInt;

begin
  // functionのResultに渡してあげる事で、メソッドを連続して
  // 記述できる様になります。
  // 例:HogeInt.Inc.Inc.Inc等
  Result := Self + 1;
end;

end.

【Unit1】メインユニット ヘルパーを利用する側

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.StdCtrls, FMX.Controls.Presentation,

  Unit2;  // ← HogeIntが定義されているユニット

type
  TForm1 = class( TForm )

    Label1      : TLabel;
    ClearButton : TButton;
    IncButton   : TButton;

    procedure FormCreate      ( Sender : TObject );
    procedure ClearButtonClick( Sender : TObject );
    procedure IncButtonClick  ( Sender : TObject );

  private
    { private 宣言 }
    Count : HogeInt;

  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.FormCreate( Sender : TObject );

begin
  Count.Clear;
  Label1.Text := Integer( Count ).ToString;
end;

procedure TForm1.ClearButtonClick( Sender : TObject );

begin
  Count.Clear;
  Label1.Text := Integer( Count ).ToString;
end;

procedure TForm1.IncButtonClick( Sender : TObject );

begin
  Count := Count.Inc;
  Label1.Text := Integer( Count ).ToString;
end;

end.

※ HogeIntを作りClearとIntメソッドを追加。
 従来のIntegerが持つToString等はキャンセルされてしまうので、
 HogeIntでToStringを使いたい場合は、Integer型でキャストする事で使用可能。
 例:Integer( HogeInt.Inc ).ToString;


今では日付&時刻計算やトークン切り出しのヘルパー等を作ってます。

Label1.Text := HogeDateTime.AddMinute( 3 ).ToSecond.ToString;
Label1.Text := HogeTokun.Tokun( 5 ).ToLength;

などと書く事ができ、利用するコード側で読みやすくなり、大変重宝しています。


[11197] Re:レコードヘルパー(と言うのかな?)が面白い返信 削除
2017/5/27 (土) 22:34:49 Mr.XRAY
> 案外この便利さを知らない方もいるかと思いまして投稿しました。

おおっ !
レコード型の Helper って,こういうふうに使うのですか.
なるほど.
Delphi XE5 でコンパイルしたら,FMX.Controls.Presentation で未定義.
Delphi Berlin Starterでやってみました.
Delphi XE3 あたりからでしょうか.いろいろな型の Helper が実装されていますね.
String, TChar とか... どんどん便利にはなっているようですが...



[11199] Re2:レコードヘルパー(と言うのかな?)が面白い返信 削除
2017/5/28 (日) 21:39:21 Konnoya
▼ Mr.XRAYさん

返事が送れてすみません。
土日をかけて家の草むしりに没頭してたものですから(笑)
案外、草むしりも地道な作業で、運動にもなりメンタルを養うのには
結構いいものです。
草むしりはさておき…(笑)

レコードヘルパーですが、Object Pacal HandBook の 357ページ に記述があり、
「今後変更される可能性があり、あまり使用しないで下さい。」
と、書かれてありましたがどうなんでしょうね?
私の読解力がイマイチ(汗

Integer型やString型の別名を作り、拡張できるのですごく便利なのですが(汗

レコードヘルパーを使うと日本語の様な感じで記述できます。

> Label1.Text := HogeDateTime.AddMinute( 3 ).ToSecond.ToString;
上記の例では、日付時刻の値に、3分加算し、それを秒に直し、文字列にせよ。
といった具合で。

あと、inline識別子は、関数呼び出しではなくコード中に組み込むものだと
思ってましたが、これはコンパイラへの「提案」という形らしくて
必ずしも組み込まれるものではないという事です。

ToStringの様な、

Result := IntToStr( Self );

といった、単純な物なら組み込まれると思いますが。

あと、レコードヘルパはいつから利用可能なんでしょうね。
手持ちのDelphi 2010ではダメでした。怒られました(笑)
Delphi XE8ではOKでした。

> Delphi XE3 あたりからでしょうか.いろいろな型の Helper が実装されていますね.
> String, TChar とか... どんどん便利にはなっているようですが...


私もまだまだ勉強不足ですね。
もっと精進しなければ(^-^)


[11206] Re3:レコードヘルパー(と言うのかな?)が面白い返信 削除
2017/6/10 (土) 09:19:18 DEKO
> あと、レコードヘルパはいつから利用可能なんでしょうね。
> 手持ちのDelphi 2010ではダメでした。怒られました(笑)
> Delphi XE8ではOKでした。


・クラスヘルパー&レコードヘルパーは 2006 から
・フル機能は 2009 から
・プリミティブ型 (Integer とか) へのヘルパーは XE4 から
・拡張元のクラスやレコードの private メンバにアクセスできなくなったのが 10.1 Berlin から

です!

[11207] Re4:レコードヘルパー(と言うのかな?)が面白い返信 削除
2017/6/10 (土) 10:01:53 DEKO

[11208] Re5:レコードヘルパー(と言うのかな?)が面白い返信 削除
2017/6/10 (土) 19:45:59 Mr.XRAY
> 関連記事を書いてみました。
> http://ht-deko.com/delphiforum/?vasthtmlaction=viewtopic&t=1940


おおー !! サンクスです.

var
  i: Integer;
  s: string;
begin
  i := 100;
  s := i.ToString;
end;

これ便利ですよね.ホント...


[11211] Re6:レコードヘルパー(と言うのかな?)が面白い返信 削除
2017/6/10 (土) 22:56:26 Konnoya
▼ DEKO様、Mr.XRAY様

返信ありがとうございます。
こういった手法を使う事により、Delphi2010 でも出来るんですね。
未だに Delphi2010 を使用しているので、情報は助かります(^-^)

INCM/CMT
Cyclamen v3.82