2015年11月5日木曜日

Lua でテーブルの内容を知りたいときは次のようなコードを使用します。

for k, v in pairs(table) do
  print(k .. " = " .. v)
end


pairs関数により、k にはキーが、vにはそのキーの値が返されます。

すべてのグローバル変数は _G というテーブルに格納されています。よって、

for k, v in pairs(_G) do
  print(k .. " = " .. v)
end


とすると全てのグローバル変数の情報を知ることができます。Lua では関数も全て変数として扱われますので、FlashAir などのような Lua を使える機器の隠しコマンドを発見するのに便利です。

2015年11月4日水曜日

UTF8文字列とUTF16文字列の相互変換

FPC 2.x で、UTF8文字列とUTF16文字列を相互に変換するには、次のように、UTF8Encode 関数、UTF8Decode 関数を使うのが一般的でした。










ソースファイルのコードページが UTF8 (デフォルト)の場合:

var
  s: string;
  ws: widestring;
begin
  s := 'あいうえお';
  ws := UTF8Decode(s);
  s := UTF8Encode(ws);
end;

FPC 2.x では、string 型の変数に ANSI 文字列が格納されているのか、それとも UTF8 文字列が格納されているのかを管理するのはプログラマのみの責任でした。
FPC 3.0 では最新の Delphi と同じく、 string 型にコードページという概念が追加されましたが、FPC 3.0 でも、string 型のデフォルトは UTF8 ですので、UTF8Encode 関数、UTF8Decode 関数を使用した上記コードは正しく動作します。もっとも、FPC 3.0 では、コードページという概念の追加により FPC 側が string 型の変数に何のコードページの文字列が格納されているのかを知ることができるようになったことから、コードページが異なる文字列の代入時に FPC が文字コードの変換を自動的に行うようになりました。なお、自動変換なんて余計なお世話だよ、という方は、 RawByteString 型を使用すれば自動変換を回避できます。

よって、FPC 3.0 では上記の例は次のように書くことができます。
なお、FPC 3.0 では widestring 型と unicodestring 型が厳密には異なるものとされるので、特に拘らない場合は unicodestring 型を使うのが無難です。ユニコード=16ビットではないので疑問の残るネーミングではありますが、Delphi のメーカーがそのようにネーミングしたので仕方ありません。


var
  s: string;
  s16: unicodestring;
begin
  s := 'あいうえお';
  s16 := unicodestring(s);
  s := string(s16);
end;

Decode や Encode という、どっちがどっちかよくわからない命名に悩まなくてよくなるだけでなく、ソースファイルのコードページが UTF8 でない場合にも対応できるようになります。
ちなみに、ソースファイルのコードページは、IDE でソースファイルを右クリックして、File Settings -> Encodeing で変更できます。