nakamurakko’s diary

たまに書く

TStringHelperの弱点

実行環境:Delphi XE7 Professional Update 1

TStringHelperが用意された事で、文字列操作が

  1. Trim(' Hello ');


から

  1. ' Hello '.Trim


のように書けるようになった。

ただ困ったのは、例えば、TMaskEditが持っているTextプロパティに対して、

  1. MaskEdit1.Text.Trim


のように書くとコンパイルエラーになる。

  1. Trim(MaskEdit1.Text)


は問題ない。

Textプロパティの型定義はTMaskedTextとなっているため、「Text.Trim」と書けないらしいけど、TMaskedTextの定義を見るとUnicodeString(ソースを見るとstring)となっているから、

  1. string(MaskEdit1.Text).Trim


みたいにキャストすればコンパイルエラーは出なくなった。

TStringHelper(ヘルパークラス)は再定義されたstring型までは追えないらしいから、キャストするしかないのかな。

Delphiで文字列結合が楽になった

1.実行環境:Delphi XE7 Professional Update 1

Javaの「String,join」がDelphiでも出来ないかと思っていたけど、Delphi XE3から出来るようになっていたらしい。
気づいてなかった。

  1. program ConsoleApp;
  2. {$APPTYPE CONSOLE}
  3. uses
  4.   System.Classes,
  5.   System.SysUtils;
  6.  
  7. var
  8.   stringList: TStringList;
  9.   messageText: string;
  10. begin
  11.   stringList := TStringList.Create;
  12.  
  13.   // 文字列「aaa」「bbb」「ccc」を設定。
  14.   stringList.Append('aaa');
  15.   stringList.Append('bbb');
  16.   stringList.Append('ccc');
  17.  
  18.   // 1.カンマ区切りで出力。
  19.   messageText := stringList.DelimitedText;
  20.   Writeln('1.' + messageText);
  21.  
  22.   // 2.区切り文字を「&」に変えて出力。
  23.   stringList.Delimiter := '&';
  24.   messageText := stringList.DelimitedText;
  25.   Writeln('2.' + messageText);
  26.  
  27.   // 3.区切り文字を「 and 」で出力。
  28.   messageText := string.Join(' and ', stringList.ToStringArray);
  29.   Writeln('3.' + messageText);
  30.  
  31.   stringList.Free;
  32. end.



出力結果
1.aaa,bbb,ccc
2.aaa&bbb&ccc
3.aaa and bbb and ccc

 

TStringListのDelimitedTextはDelimiterを変更する事で区切り文字を変更出来たけど、設定できるのはCharのため、2バイト以上設定出来なかった。
Delphi XE3から導入されたTStringHelperのおかげでstring型が拡張されて、「string.join」が書けるようになり、第1引数「Separator」はstringのため、2バイト以上の区切り文字に指定出来るようになっている。

これは便利。

 

<2015/09/11>

ソースを一部修正。

CentOS 7でclamdがこける場合の対処

CentOS 7にclamdを起動しようとすると下記のようなメッセージが出る。
Job for clamd.service failed. See 'systemctl status clamd.service' and 'journalctl -xn' for details.

その時はどうやら起動時にSocketファイルを作成しようとして、指定ディレクトリが無いから、らしいので、
# mkdir /var/run/clamav
# chown clamav:clamav /var/run/clamav
を実行してディレクトリ作成+所有者設定してあげるとうまくいく。
(2014/11/12時点)


2014/11/18 追記
「/var/run/」以下はシャットダウン時に消えるから、起動するたびに実行する事になってしまうね…。

 

2015/05/08 追記

tmpfiles.dで対処出来るから問題無かった。

Delphi七不思議の一つ(個人的な)

Genericsの実装で
・リスト系→存在する(TObjectList)
・ディクショナリ系→存在する(TObjectDictionary)
・セット系→存在しない!(TObjectSetみたいなクラスが無い)
というのがDelphi XE7でも変わらず。

何か理由があるのだろうか?

Delphiで手抜きインターフェース取り込み

Delphiにもインターフェースは存在する。
全てのインターフェースの基本クラスは「IInterface」。

ただし、Javaや.NETとは違い、インターフェースを継承すると
・_AddRefと_Release(参照カウントメソッド)
・QueryInterface(指定したインターフェイスへの参照を返す)
も実装する必要があるので、

  1. THoge = class(TObject, IInterface)


とだけ書くとコンパイルエラーになる。(「IInterface.QueryInterface の実装が見つかりません」などのエラーが3つ出る。)

そこで、「既に実装が終わっているクラスを取り込む」という手抜き実装を行う。
Delphiのクラス階層で最初に出てくるでインターフェースの実装が最初に行われているのは「TComponent」。

つまり、

  1. THoge = class(TComponent, IInterface)


と書くとコンパイルエラーが無くなる。

例えば、インターフェースを

  1. IInformation = interface
  2.   procedure GetInfo;
  3. end;


と用意し、そのインターフェースを使用するクラスを、TComponentを継承して実装する。

  1. TInformation = class(TComponent, IInformation)
  2.   procedure GetInfo; // これは実装する。
  3. end;


とすれば、AddRef、_Release、QueryInterfaceはTComponentで実装済みなので、自分で書く必要が無くなる。

TComponent以下であればTButtonなどでも出来るけど、TComponentを継承していないクラスやTComponentの親クラス(TPersistent、TObject)を継承する場合は_AddRef、_Release、QueryInterfaceを自分で実装するしか無さそう。TObjectから派生したTInterfacedObjectを使えば良い、という事をpikさんから教えてもらいました。ありがとうございました。

TInterfacedObjectの定義を見ると、

  1. TInterfacedObject = class(TObject, IInterface)


となっているため、今回の用件を満たしている。
なので、

  1. TInformation = class(TInterfacedObject, IInformation)


もAddRedなどを自分で書く事無く使用可能。

Windows AzureでワークグループのWin8にMicrosoftアカウントでログインする

実行した環境:Windwos 8.1 Enterprise (64ビット)

ドメインが異なる環境へのリモートデスクトップは、少し手間がかかるようだ。
リモートデスクトップ接続を使用して接続できない理由

証明書の準備も必要だったりするようなので、別の方法は無いかと思い、Windows AzureにWORKGROUP設定のままMicrosoftアカウントでログインするためにやった事。

・コントロールパネルの「ユーザアカウント」で、新規ローカルアカウントを作成する。
 (必要であれば管理者ユーザに設定。)

・システムのプロパティのリモートタブを開き、「ユーザーの選択」ボタンをクリック。
・新規ローカルアカウントをリモートデスクトップユーザーに追加する。

・新規ローカルアカウントでログイン後、チャームバーの「PC設定の変更」をクリック。
・「お使いのアカウント」で「Microsoftアカウントを関連付ける」のリンクをクリックして、Microsoftアカウントを関連付けるウィザードを実行する。

上記を完了すると、新規ローカルアカウントとMicrosoftアカウントが関連付いた状態でリモートデスクトップが利用可能になる。