Hatena::ブログ(Diary)

四角革命前夜

2011年10月10日(月)

UTF-8のソースコードに文字列定数を書いたらそのままUTF-8になったお話

program test;

uses
  Windows;

begin
  WriteLn(lstrlenW('あ'));  { 3 }
end.

と書いたら3が返ってきて、びっくりですよ。

ソースコードUTF-8だからUTF-8で定数が保存されたのでしょうか。

program test;

uses
  Windows;

begin
  WriteLn(lstrlenW(#$3042));  { 1 }
end.

でちゃんと1が返ってきました。


追記:

ソースコードが、じゃなくてそもそも内部ではUTF-8を使ってるんでした。

多分それのせいかと。なので文字列定数に対してUTF8Decodeとか使えばUTF-16として戻ってくるはず。


追記2:

program test;

{$MODE OBJFPC}

uses
  Windows;

var
  s: WideString;
begin
  s := UTF8Decode('あ');
  Writeln(lstrlenW(s)); { 1 }
end.

うーむ……

2011年10月07日(金)

fptestの使い方

久しぶりにPascalが触りたくなったのでFreePascalでアプリを書こうかと。

といっても昔作ったやつをまた作り直してるってだけなんですが……


Delphi向けのユニットテストライブラリとしてDUnitなんてのがありましたが、

更新も止まっているみたいで、DUnit2も進捗がないようです。(多分)

今回はFreePascalを使うのですが、DUniteは以前使った記憶ではFreePascalで使えなかったのですよね。

他にないのか探してみたらgithubにfptestというDUnit2からフォークしたものがあるではないですか。

そういうわけで今回はこれを使うことにしたのでした。

GitHub - graemeg/fptest: Testing framework for the Object Pascal language using the Free Pascal compiler.


テストユニット

unit Aaa;

interfaces

uses
  TestFramework;

type
  TTestCaseAaa = class(TTestCase)
  published
    procedure TestOne;
  end;

procedure RegisterTests;

implementation

procedure TTestCaseAaa.TestOne;
begin
  Check(1 + 1 = 2, 'TTestCaseAaa#TestOne');
end;

procedure RegisterTests;
begin
  TestFramework.RegisterTest(TTestCaseAaa.Suite);
end;

end.

テストユニットはこんな感じ。

TTestCaseを継承してpublishedでテストメソッドを書いてあげればOKです。


テストの登録・実行

program test;

uses
  Aaa, TextTestRunner;

begin
  Aaa.RegisterTests;
  RunRegisteredTests;
end.

呼ぶ方はこれだけです。


コンパイル・実行

$ fpc -Mobjfpc -WC -Fu.\fptest\src test.lpr
$ test.exe

これコンパイルと実行を。今回はTextTestRunnerをusesに入れたので、

コマンドライン用にコンパイルしましたが、GUI用のGUITestRunnerもあるようです。

2011年04月17日(日)

ctagsで引数付きメソッド一覧

ctagsってエディタの補完用ファイルを生成するだけじゃないんだね!っていうメモです。


引数付きのメソッド一覧が必要になったことがあって、ctagsの生成するtagsファイルが使えるかも、と思って見てみたら引数が書いてなかったのです。(/ /で囲われているところはエディタが検索に使う部分なので、引数の途中で改行されていると途中までしか書いてない)

「ええー、Javaのパーサーなんて書けないよ?」と思って、一応ctagsのオプションを調べたら引数も書いてくれるオプションがあるではないですか。便利ですねえ。

エディタの補完用途にしか使えないのだとばかり思っていたら割と高機能・多機能で…… これからもお世話になります。


$ ctags -R --fields=+KS

-Rはカレントディレクトリ以下を再帰的に検索、--fieldsの+がONにする、という意味で、-にするとOFFに。

Kがmとか表示されるところがmethodと長く記述されるようにするオプションで、Sが引数のリストを記述するオプション。(オプション?)


試しに以下のソースでtagsファイルを生成してみると……

{ aaa.pas }
unit aaa;

function bbb: Boolean;
procedure ccc;
procedure ddd(const Value: String); overload;
procedure ddd(Value: Integer); overload;

implementation

function bbb: Boolean;
begin

end;

procedure ccc;
begin

end;

procedure ddd(const Value: String); overload;
begin

end;

procedure ddd(Value: Integer); overload;
begin

end;

end.
// aaa.java
class aaa {
  public static void main() { }
  public void bbb() { }
  public void bbb(String str) { }
  public void bbb(int l,
    String str,
    int n) {}
  public void ccc(int i) { }
}

aaa	aaa.java	/^class aaa {$/;"	class
bbb	aaa.java	/^  public void bbb() { }$/;"	method	class:aaa	signature:()
bbb	aaa.java	/^  public void bbb(String str) { }$/;"	method	class:aaa	signature:(String str)
bbb	aaa.java	/^  public void bbb(int l,$/;"	method	class:aaa	signature:(int l, String str, int n)
bbb	aaa.pas	/^function bbb: Boolean;$/;"	function
ccc	aaa.java	/^  public void ccc(int i) { }$/;"	method	class:aaa	signature:(int i)
ccc	aaa.pas	/^procedure ccc;$/;"	procedure
ddd	aaa.pas	/^procedure ddd(Value: Integer); overload;$/;"	procedure
ddd	aaa.pas	/^procedure ddd(const Value: String); overload;$/;"	procedure
main	aaa.java	/^  public static void main() { }$/;"	method	class:aaa	signature:()

こんな感じ。Pascalのソースは引数を解析してくれない……

Javaのaaa#bbb()メソッドは/ /で囲まれてるところは途中で改行されてるから引数が全部表示されてないけど、後ろのsignatureのところに全部列挙されてます。


これでパーサを書く必要もなくなり、grepやsed/awkでごにょごにょして事なきを得たのでした。

2010年12月16日(木)

独習Java第10章 Javaクラスライブラリの初歩(10.4)

ジェネリクスやVectorクラス、Enumratorインターフェースにイテレータなどの章。

10.1から10.3まではRandomとかCalendarとかだけど、ほぼ使えるので放置しておく。

環境:UbunruNetbookRemix 10.10 / Oracle(Sun) JDK6 update22


Vectorクラス

いわゆる動的配列でいいのかな。


ジェネリクスを指定できるところはオプションなので、指定しなくてもOKらしい。

$ javac -Xlint:unchecked

とパラメータを付けると、ジェネリクスを使わないでオブジェクトを操作している箇所が見れるとか。


ジェネリクスで使われる慣例の型パラメータには

パラメータ意味
E要素
Kキー
N
T
V

があるらしい。Element, Key, Number, Type, Valueの頭文字かな?


書いてみる

// VectorSample.java
import java.util.*;

class VectorSample
{
  public static void main(String args[])
  {
    Vector<String> vector = new Vector<String>();
    vector.add("1");
    vector.add("2");
    vector.add("3");
    vector.add("4");
    vector.add("5");

    Iterator iterator = vector.iterator();

    while (iterator.hasNext())
    {
      System.out.println(iterator.next());
    }
  }
}

実行してみる

$ javac VectorSample.java
$ java VectorSample
1
2
3
4
5

……感動が少ない。


ソース書き終わってから調べてみたら、Vectorは古いし速度的に遅いからArrayListとかの方が使われるとかなんとか。

まあ、ジェネリクスの書き方を知らなかったし、良しとするか。


動的配列ねえ……

const
  ARRAY_SIZE = 5;
var
  i: Integer;
  ary: array of Integer;
begin
  SetLength(ary, ARRAY_SIZE);
  ary[0] := 1;
  ary[1] := 2;
  ary[2] := 3;
  ary[3] := 4;
  ary[4] := 5;
  for i := Low(ary) to High(ary) do
    Writeln(ary[i]);
  ary := nil;
end.

ObjectPascalだったらすぐ書けるんだけどなー。


とりあえず今のところ普通に使われる動的配列(リスト?)はArrayListとLinkedListで、前者はget()とかが速く、後者は挿入とか削除が速いらしい。

多分、前者は一般的な配列のような実装…な気がする。

後者はC言語とかの「前後の要素が持っている、その要素へのポインタを付け替える」だけ、みたいな実装…かな。わかんないけど。

クラス名といい、その特徴といい、多分そうなんだろう。多分。