2009年10月26日月曜日

IOUtilsユニットをつかってみる(その1)

Delphi2010で追加されたIOUtilsユニットを使ってファイルリスト
(正確にはファイル名のリスト)を取得するだけであれば、

TDirectory.GetFilesメソッドで簡単に取得できます。

Delphi Prism(.Net版)とほぼ同じ形でかけます



GetFilesメソッドはいくつかOverLoadの定義がありますが、

今回は、

function GetFiles(const Path: string;
const SearchPattern: string;
const SearchOption: TSearchOption): TStringDynArray; overload; static;


を使用した簡単なサンプルを作ってみました。

ここで、Pathは検索パス
    SearchPatternは、検索パターン(全検索は'*')
  SearchOptionは、
     サブディレクトリも検索するときはsoAllDirectories
     指定したディレクトリのみを検索するときは、soTopDirectoryOnly
を指定します。

以下、サンプルプログラム


procedure TForm1.ButtonExecGetFileClick(Sender: TObject);
var
MyDir : IOUtils.TDirectory;
FileList : TStringDynArray;
FileName : String;
begin

ListBox1.Clear;

if Self.CheckBoxFindSubDir.Checked then
begin
FileList := MyDir.GetFiles(EditStartPath.Text,'*',TSearchOption.soAllDirectories);
end
else
begin
FileList := MyDir.GetFiles(EditStartPath.Text,'*.XLS',TSearchOption.soTopDirectoryOnly);
end;

for FileName In FileList do
begin
ListBox1.Items.Add(FileName);
end;

end;


と結構簡単にかけます。
(ただ、ファイル数が多いとなかなか帰ってこないです。)

2009年10月24日土曜日

Delphi 2010 Survey

http://wings-of-wind.com/2009/10/23/newsflash-the-official-delphi-2010-survey/

によると、Delphi Surveyが始まったみたいだ。

来週か、再来週には、日本語でできるのかな?

2009年10月7日水曜日

Rttiを使ってClientDataSetを作ってみる

以前、Team JapanのブログにEmployeeクラスのインスタンスからInsert文を
生成するサンプル
のポストがありましたが、ちょっと改良してTClientDataSetを
動的生成する例を書いてみた。(って使い道があるかちょっと疑問です。)

一応ソースは、こんな感じ

unit Unit3;

interface

uses
  DBClient;

type DataSetOperator = Record
function CreateDataSet(obj : TObject) : TClientDataSet;
function AddRecord(cds : TClientDataSet; obj : TObject) : Boolean;
End;


implementation

uses
Rtti,TypInfo, DB, SysUtils;
{ DataSetFactory }

function DataSetOperator.AddRecord(cds: TClientDataSet; obj: TObject): Boolean;
var
ctx : TRttiContext;
rtp : TRttiProperty;
rtps : TArray;
begin

ctx := TRttiContext.Create;

rtps := ctx.FindType(obj.UnitName + '.' + obj.ClassName).GetProperties;
cds.Append;
for rtp in rtps do
begin
cds.FieldByName(rtp.Name).Value := rtp.GetValue(obj).AsVariant;
end;
cds.UpdateRecord;
end;

function DataSetOperator.CreateDataSet(obj: TObject): TClientDataSet;
var
ctx : TRttiContext;
rtp : TRttiProperty;
rtps : TArray;
cds : TClientDataSet;
ft : TFieldType;
fn : String;
ftSize : Integer;
//ftdf : TFieldDef;
begin

cds := TClientDataSet.Create(nil);

ctx := TRttiContext.Create;

rtps := ctx.FindType(obj.UnitName + '.' + obj.ClassName).GetProperties;

for rtp in rtps do
begin
//ここがちょっとダサイかも
//DelphiのRTTIの型とDBの型のマッチング
ftSize := 0;
if CompareText(rtp.PropertyType.Name,'Integer') = 0 then ft := ftInteger;
if CompareText(rtp.PropertyType.Name,'String') = 0 then
begin
ft := ftString;
ftSize := 50;
end;
if CompareText(rtp.PropertyType.Name,'TDateTime') = 0 then ft := ftDateTime;
if CompareText(rtp.PropertyType.Name,'Currency') = 0 then ft := ftCurrency;
//if CompareText(rtp.PropertyType.Name,'Currency') = 0 then ft := ftCurrency;

cds.FieldDefs.Add(rtp.Name,ft,ftSize);

end;
cds.CreateDataSet;
Result := cds;
//cds.FieldDefs.Add();

end;

end.

DBのデータ型の列挙とRTTIのデータ型の列挙が微妙に違っているので
そのマッピングを少々強引に行ってます。

で、上のユニットを利用する例が


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, Grids, DBGrids;

type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
DataSource1: TDataSource;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

uses Unit2, Unit3,DBClient;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
Emp : TEmployee;
DF : DataSetOperator;
cds : TClientDataSet;
begin

Emp := TEmployee.Create;

cds := DF.CreateDataSet(Emp);
cds.Active := true;
DataSource1.DataSet := cds;
//DataSource1.DataSet.Active := true;

Emp.EmpNo := 2;
Emp.FirstName := 'OldTPFun';
Emp.LastName := 'Delphi';
Emp.HireDate := StrToDate('2009/10/07');
Emp.Salary := 100000.00;
DF.AddRecord(cds,Emp);

Emp.Free;
end;

end.


このプログラム上で使っているEmployee型の定義は以下のとおりです。



unit Unit2;

interface

type TEmployee = class
private
FEmpNo: Integer;
FFirstName: String;
FLastName: String;
FHireDate: TDateTime;
FSalary: Currency;
procedure SetEmpNo(const Value: Integer);
procedure SetFirstName(const Value: String);
procedure SetLastName(const Value: String);
procedure SetHireDate(const Value: TDateTime);
procedure SetSalary(const Value: Currency);
public
property EmpNo : Integer read FEmpNo write SetEmpNo;
property FirstName : String read FFirstName write SetFirstName;
property LastName : String read FLastName write SetLastName;
property HireDate : TDateTime read FHireDate write SetHireDate;
property Salary : Currency read FSalary write SetSalary;
end;
implementation

{ TEmployee }

procedure TEmployee.SetEmpNo(const Value: Integer);
begin
FEmpNo := Value;
end;

procedure TEmployee.SetFirstName(const Value: String);
begin
FFirstName := Value;
end;

procedure TEmployee.SetHireDate(const Value: TDateTime);
begin
FHireDate := Value;
end;

procedure TEmployee.SetLastName(const Value: String);
begin
FLastName := Value;
end;

procedure TEmployee.SetSalary(const Value: Currency);
begin
FSalary := Value;
end;

end.

2009年9月3日木曜日

TValue型を試してみる

Rttiユニットで新たに定義されたTValue型は、汎用に使えるデータ型に
なっていて、Delphiで使う基本的な型は、Implicit演算子が定義されており
代入可能になっている。

で、実験してみた。以下ソースコード



program Project1;
{$APPTYPE CONSOLE}

uses
SysUtils,
rtti,
typinfo;

var
tv: TValue;
obj: TObject;
intary: Array of TValue;

begin
try
{ TODO -oUser -cConsole Main : ここにコードを記述してください }
// 先ずは何も入れない場合
if tv.IsEmpty then
begin
writeln('TValueはからです');
end;

tv := 100;
writeln('TValueは' + tv.TypeInfo.Name + 'です。');

tv := 100.0;
writeln('TValueは' + tv.TypeInfo.Name + 'です。');

tv := 'saka';

writeln('TValueは' + tv.TypeInfo.Name + 'です。');

obj := TObject.Create;
tv := obj;
writeln('TValueは' + tv.TypeInfo.Name + 'です。');

tv := obj.ClassType;
writeln('TValueは' + tv.TypeInfo.Name + 'です。');

obj.Free;

end.



で実行した様子が下図。

2009年8月29日土曜日

Rttiを試してみるその4

以前のポストで、可視性がPrivateのメソッドは、読めないということを
記述しましたが、実際には、

自分で定義したメソッドであれば

コンパイラ指定{$RTTI EXPLICIT METHODS}で
TRttiContextのGetMehtodで列挙する可視性を制御することが可能のようです。

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic,vcProtected,vcPrivate])}

とすれば、すべての可視性の列挙が可能です。(正し、継承元のメソッドには
可視性の制御は及ばない見たいです。)

また、

{$RTTI EXPLICIT METHODS([vcPrivate])}

とすれば、Private可視性のメソッドの列挙が可能です。

以下、検証ように使ったソースです。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, CheckLst;

type
TForm1 = class(TForm)
Button1: TButton;
CheckListBox1: TCheckListBox;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

uses Rtti,Typinfo,Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
ctx : TRttiContext;
rtmary : TArray;
rtm : TRttiMethod;
obj : TObject;
Args : Array of TValue;
rtp : TRttiType;
idx : Integer;
begin

ctx := TRttiContext.Create;

//自分で定義したメソッドのみを取得するには、
//GetDeclaredMethodsを使います。
rtmary := ctx.GetType(Unit2.TSakaTest).GetDeclaredMethods;
//rtmary := ctx.GetType(Unit2.TSakaTest).GetMethods();

CheckListBox1.Clear;

if rtmary <> nil then
begin
for rtm in rtmary do
begin
idx := CheckListBox1.Items.Add(rtm.Name);
if rtm.Visibility = TMemberVisibility.mvPrivate then
begin
CheckListBox1.Checked[idx] := true;
end;

end;

end;

end;

end.






unit Unit2;
interface

uses classes;

// {$RTTI EXPLICIT METHODS([vcPublished,vcPublic,vcPrivate])}
{$RTTI EXPLICIT METHODS([vcPrivate])}
Type TSakaTest = Class(TObject)
private
function SayPrivateMessage : String;
public
function SayPublicMessage : String;
End;

implementation

{ TSakaTest }

function TSakaTest.SayPrivateMessage: String;
begin
Result := 'This is a Private Method';
end;

function TSakaTest.SayPublicMessage: String;
begin
Result := 'This is a Public Method';
end;

end.

Rttiを試してみるその3

文字列で指定したクラスのインスタンスを作成する例を作ってみました。
(Button3Click)
試行錯誤のうえで作成したソースなので、とりあえず動きましたが
正しいソースかどうかは、分かりません。もっと良い方法が
あれば教えて下さい。

この手の処理はActivatorクラスのある.Netのほうが簡単だと
思います。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,Unit2;

type
TForm2 = class(TForm)
Button3: TButton;
LabeledEdit1: TLabeledEdit;
ListBox1: TListBox;
Button1: TButton;
Label1: TLabel;
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
protected
public
{ Public 宣言 }

end;

var
Form1: TForm2;
implementation
uses
Rtti,TypInfo;

{$R *.dfm}


procedure TForm2.Button1Click(Sender: TObject);
var
LContext: TRttiContext;
LType: TRttiType;
LTypes:TArray;

begin

LoadPackage('SakaPack.bpl');

{ Obtain the RTTI context }
LContext := TRttiContext.Create;

{ Obtain the second package (rtl140) }
LTypes := LContext.GetTypes();

{ Enumerate all types in the rtl140 package }

//for LPackage in LPackages do
//begin
for LType in LTypes do
begin
ListBox1.Items.Add(LType.QualifiedName);
end;
//end;
ListBox1.Items.SaveToFile('P.Txt');

end;

procedure TForm2.Button3Click(Sender: TObject);
var
ctx : TRttiContext;
rtm : TRttiMethod;
rst : TValue;
SakaInf : ISakaTest;
rtt : TRttiType;
Args : Array of TValue;


begin

//とりあえず別パッケージで動的ロード化とする
LoadPackage('SakaPack.bpl');

ctx := TRttiContext.Create;

//文字列で型情報を探す場合は、FindTypeを使う
//完全一致なのでユニット名を含めて指定
rtt := ctx.FindType('Unit2.' + LabeledEdit1.Text);

//コンストラクタはとりあえずCreateであることが前提
rtm := rtt.GetMethod('Create');

if rtm <> nil then
begin
if rtm.IsConstructor then
begin
//1. クラスの場合は、TRttiInstanceTypeで戻ってくるのでキャスト
//2. MetaaclassTypeプロパティで実際のクラスがとれるみたい。
rst := rtm.Invoke(TRttiInstanceType(rtt).MetaclassType,Args);
if rst.IsObject Then
begin
SakaInf := TSakaTest(rst.AsObject) As ISakaTest;
Label1.Caption := SakaInf.SayMessage();
end;
//Label1.Caption := obj.ClassName;
end;
end;


end;

end.


でUnit2で使ったソースがこちら



unit Unit2;

interface
uses classes;

{$RTTI EXPLICIT METHODS([vcPublic])}
Type ISakaTest = interface(IInterface)
['{FAAA20A5-E078-4E22-96C2-139E7E57CBFB}']
function SayMessage : String;
end;

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
Type TSakaTest = Class(TInterfacedPersistent, ISakaTest)
function SayMessage : String; virtual;
End;

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
Type TSakaTest1 = Class(TSakaTest)
Public
function SayMessage : String; override;
End;

{$RTTI EXPLICIT METHODS([vcPublished,vcPublic])}
Type TSakaTest2 = Class(TSakaTest)
Public
function SayMessage : String; override;
End;

var
SakaTest : ISakaTest;

implementation

//uses
//Classes;



{ TSakaTest1 }

function TSakaTest1.SayMessage: String;
begin
Result := 'Hello Delphi First';
end;

{ TSakaTest2 }

function TSakaTest2.SayMessage: String;
begin
Result := 'Hello Delphi Second';
end;

{ TSakaTset }

function TSakaTest.SayMessage: String;
begin
Result := '';
end;

initialization
RegisterClass(TSakaTest);
RegisterClass(TSakaTest1);
RegisterClass(TSakaTest2);

end.

Jedi VCL Versionアップ

Delphi 2010の対応です。

ユニットを使うダイアログ


Unitの追加先を選択できるようになってたんだ。
気づかなかった。

Rttiを試して見るその2

前回のポストに引き続いて、メソッドの動的呼び出し。

整数の足し算を行う例です。以下ソース


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Button3: TButton;
LabeledEdita: TLabeledEdit;
Label1: TLabel;
LabeledEditb: TLabeledEdit;
Label2: TLabel;
LabelResult: TLabel;
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
protected
public
{ Public 宣言 }
function Sakasum(a,b : Integer) : Integer;

end;

var
Form1: TForm1;

implementation
uses
Rtti,TypInfo;

{$R *.dfm}


procedure TForm1.Button3Click(Sender: TObject);
var
ctx : TRttiContext;
rtm : TRttiMethod;
Args : Array of Rtti.TValue;
rst : TValue;
begin
//
ctx := TRttiContext.Create;
rtm := ctx.GetType(Self.ClassType).GetMethod('SakaSum');

if rtm <> nil then
begin
SetLength(Args,2);
//TValueは、演算子Implicitが定義されているので基本的な型は
//変換による代入が可能
Args[0] := StrToInt(LabeledEdita.Text);
Args[1] := StrToInt(LabeledEditb.Text);
rst := rtm.Invoke(Self,Args);
//結果はAsXXXXX関数を使って取り出せる。
Self.LabelResult.Caption := IntToStr(rst.AsInteger);
end;
end;


function TForm1.Sakasum(a, b: Integer): Integer;
begin
Result := a + b;
end;

end.


TValueの使い方が分からなくて結構悩みました。

で、ソースをみたら基本的な型については、
Implicit演算子のオーバーロードが
定義されているのね。

このへんはHelpに書いといて欲しかったです。
(C++ のHELPには書いてあります。)

(英語版のDoc Wikiがメンテナンス中だったので
日本語版でのみ書いていないのかはちょっと不明です。)

また、こちらにDelphi Prismで上記と同様な処理を
記述しました

2009年8月28日金曜日

Rttiを試して見る

動的にメソッドを読み出す簡単なプログラムを作ってみました。
プログラムそのものには意味はありません。

プレビュー会に説明があったようにprivateなメソッドは読めませんでした。
メソッドの可視属性を示す型があったので読めてもよいと思ったのですが・・・

また、GetDeclaredMethodsをつかうと自分が宣言したメソッドのみ
リストできます。

以下ソースです。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
LabeledEdit1: TLabeledEdit;
Button2: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
//procedure SakaTest2;
protected
//procedure SakaTest1;
procedure SakaTest2;
public
{ Public 宣言 }
procedure SakaTest2;
procedure SakaTest1;
end;

var
Form1: TForm1;

implementation
uses
Rtti,TypInfo;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
ctx : TRttiContext;
rtm : Rtti.TRttiMethod;
obj : TObject;
Args : Array of TValue;
begin
//
ctx := TRttiContext.Create;


//rtm := ctx.GetType(obj).GetMethod(LabeledEdit1.Text);

rtm := ctx.GetType(Self.ClassType).GetMethod(LabeledEdit1.Text);

if rtm <> nil then
begin
//obj := Self;
rtm.Invoke(Self,Args);
end;

end;

procedure TForm1.Button2Click(Sender: TObject);
var
ctx : TRttiContext;
rtmary : TArray;
rtm : TRttiMethod;
obj : TObject;
Args : Array of TValue;
rtp : TRttiType;
begin

ctx := TRttiContext.Create;

//rtm := ctx.GetType(obj).GetMethod(LabeledEdit1.Text);
//ctx.FindType()
//rtp := ctx.GetType(Self.ClassType);
//rtp.IsPublicType := false;

rtmary := ctx.GetType(Self.ClassType).GetDeclaredMethods;

ListBox1.Clear;

if rtmary <> nil then
begin
for rtm in rtmary do
begin
ListBox1.Items.Add(rtm.Name);
if rtm.Name = LabeledEdit1.Text then
begin
rtm.Invoke(Self,Args);
end;

end;

end;

end;

procedure TForm1.SakaTest1;
begin
Application.MessageBox('Hello Delphi','First Text');
end;

procedure TForm1.SakaTest2;
begin
Application.MessageBox('Hello Delphi','Second Text');
end;

end.


引数つきのメソッドコールはまた次回

2009年8月26日水曜日

サポートプログラムの配布方法

サポートプログラムの配布方法が
メールによるキー送付に変わった。

いち早く、使用できるのは良いが
やっぱりメディアもあったほうが
良いと思う。

2009年8月25日火曜日

プログラマがマニュアル読まなくどうするの

タイトルだけみて、気分を悪くされた方すみません。

これは、あくまでも自分への戒めのためのタイトルです。

DEKO様はじめ、先日、ご助言頂いた方々どうもありがとうございました。
なお、コメントは非公開と致しますのでご了承願います。

DelphiのHelpがWikiかされたので、ちょっとのぞいていたら
書いてあるんですわ。オブジェクトインスペクタの動作が・・・

ここに

大澤の親分の張本さんに大喝を食らったうえに
タイトルの台詞で叱咤されそうですわ。

しばらくは、懺悔と精進の日々です。

Rad Stduio 2010発売

正式発表があった見たいですね。

とりあえず、値段が据え置きでよかったです。
(スタンダードサポートの更新料も据え置きのようです。)

日本の公式サイトもエンバカデロドメインに移るようで
しばらくはばたばたしそうですね。

2009年8月23日日曜日

Delphiのウィルスについて思うこと

遅ればせながらひとこと。

エンバカデロさんからは、ウィルスに関する(対策)情報を
出す準備をしているとのこと
であり、コミュニティ方々も
いろいろな情報を出している。

しかし、現状、ウィルスに狙われているバージョンは4~7で、
エンバカデロさんのサポート情報によれば、すべて
サポート終了バージョンになっている。
(将来的には、新しいバージョンがターゲットになるかも
しれません。)

従って、Delphi4~7については、エンバカデロさんが
対策をしないと言ったとしても、僕らは、文句を言うことは
できないと思う。(言ってみるのは良いと思うが取り合って
くれない可能性のほうが高い。)

僕らにできることは、通常のウィルス対策と一緒のことですが
Delphiを最新の状態に保つこと。
すなわち、メーカのサポート中のバージョンの最新アップデートに
することだと思う。

ただ、開発言語(環境)で難しいのは、その環境の
過去バージョンで作ったアプリのサポートが必要だと
思う。

Versionを上げることは、Versionアップそのものの作業と
それに伴う動作検証に多大な労力がかかり、なおかつ
DelphiのVersionアップ料で多大な費用がかかることになる。

Delphiの開発元がBorland→Codegear->Embarcaderoと
変わる間にすくなくとも日本では、値段が高くなり
個人ユーザにはものすごい負担になると思う。

また、既にDelphiでの開発を止めている企業さんも多いと思う。
これらの企業さんは、メンテナンス用に古いバージョンを
保持しているとは思うが、いまさら新バージョン投資するかどうかは、
怪しいと思う。

ただし、個人的には、上記のような理由があっても、セキュアな
システムを提供するためにはVerupは提供する側の責任で
あると思う。

2009年8月18日火曜日

穴があったら入りたい。

コメント頂いた皆様ありがとうございました。

あまりのショボさに前のエントリーを非表示と致しました。

前のエントリーについては、期間をおいてなんらかの形で
復活させたいと思います。

しかし、10年以上使っててこんな初歩的なことを
しらなかったなんて・・・・

正に、穴があったら入りたい気分です。(穴はかなり深い穴が良いです。)

もう一回基本を固めて出直しです。

2009年8月14日金曜日

IDEの配置(その1)


上の図は、自分のIDEの配置です。
Visual Studioでオブジェクトインスペクタが右にあるのに
なれちゃったのでオブジェクトインスペクタは右側に
配置しています。

また、ツールパレットなど、構造ペインなども右側に
持っています。

これは、自分が右利きだからです。

意外に便利な配置なので、右利きの人は
良かったら試して下さい。

Rad Studio 2010の値段(米国)

Info Worldの記事によれば、エンプラ版のRad Studio 2010の米国での値段は
2799ドル(日本円で約26万7千円)だそうです。

さて、日本での値段はいくらになるのでしょうか?
ちょっと心配

2009年8月11日火曜日

思いつき

Delphi2010では、マウスジェスチャーがサポートされています。

これとWilリモコンを組み合わせたら、オモシロイことが出来そうですね。
(具体案は浮かばないので単なる思いつきですが・・・)

使い勝手にこだわれること

エンバカデロさんのサイト、フィールドテスターの皆様、ブロガーの皆様から
Delphi 2010に関する情報がいろいろ出てきてます。

これらを読むにつれて、地味だけど、かなり使い勝手を重視した機能を
盛り込んでいると思う。

これで、サクサク動けば、言うことなしなのですが、プレビュー会のビデオや
プレビュー動画を見る限りでは問題無さそうなのですが・・・

個人的には、使い勝手にこだわった開発が出来ているときは、
非常に良い状態で開発が出来ていると思います。

Delphi8から始まった製品の品質に関する混乱は完全に収束しつつある
といった状況と勝手に推測しています。

Delphi8の発売が2004年(本国は2003年11月)であることを考えると
会社自体の混乱もありましたが、品質を立て直すのに5年を要しています。

この間に失った信頼を取り戻すのは容易ではないかと思いますが、
現在の状態、(メーカさんとユーザさんとで適切にコミュニケーションが
とれている状態)であれば、なんとかなっていくのではないかと思います。

個人的には、発売前の情報で買いたいと思えるバージョンなのですが
問題は、価格ですね。(最近、Ver Upの度に価格があがっていますので・・・)

2009年8月6日木曜日

Delphi 2010 プレビュー会

仕事で参加できなかったかつ社内ネットワークから
中継が見れなかったので、とりあえずTwitterをROM

気になった点を以下列挙

1) RTTIの機能強化 Private メンバーは見れないみたいですね。
  Protectメンバーが見れれば良いのだけど、どうなんでしょう?

2) C++ 系で******_S系の関数が追加されたのはGoodです。

3) midasのソースコード有るんだ?ちょっとびっくりです。

参加者の皆さんお疲れ様でした。

今頃は、場所を変えて第2段かな?

Delphi 2010 の情報へのブックマーク

Nick Hodgesさんのブログポスト

Delphi2010の情報のブックマークになっています。

とりあえず、備忘録としてリンク

EmbarcderoのBlogでも、Radstudio 2010に関する記事が
ものすごい勢いで公開されています。

ついてくのがちょっと大変((^_^;))

2009年8月5日水曜日

Win32でリフレクション

日経ソフトウェアの記事によれば

Delphi2010では、.Netのリフレクション並にRTTIが強化される
見たいです。

これは楽しみ

DbExpress Firebird Driver

Delphi Feed経由の情報です。

次期Delphi2010でサポート予定のFirebirdですが、

Chee Yang ChauさんがDelphi2007, 2009対応の

FirebirdのDbExpressドライバを開発されました。

Firebird用のDbExpressドライバを探していたので
一度テストしてみる価値はありそうです。

開発者のChee Yang Chauさんに感謝です。

2009年8月4日火曜日

IDEインサイトは便利そう

次期Delphi(delphi2010)のPreview Videoが公開されたので
早速みてみた。

以下覚え書き(内容はVideoの要旨にも書かれてます。)

IDEインサートは、IDEの状況に応じて、専用のダイアログを使って
ショートカットを提供する機能で、Videoでは、IDEインサートから
Component名を入れてフォームに貼り付けるデモをしていた。

コンポーネント名さえ覚えていれば、コンポーネントパレットを
探さなくても(今までは、コンポーネントパレット内での検索可)
コンポーネントをフォームに貼れるので大変便利だ。

また、IDEでCode Formatterをサポートするようだ。
これは、DevCampでもリクエストがあった機能だ。

また、スレッドのデバッグ、TStringsのViewerなど
デバッグ時に便利な機能が追加されている。

細かいところでは、オブジェクトインスペクタの2値の設定が
チェックでできるようになっているみたいだ。

Videoの内容だけで判断すると2010はものすごく使い勝手に
こだわったVersionのような気がします。


でも、もっとも気になったなのはDavid Iの服の色目かな(冗談です。)

2009/08/05 追記

Nick Hodges氏もdelphi2010でIDEに新搭載の機能のブログを
POSTしています。

2009年7月18日土曜日

Delphi2006 販売停止

Daniel Magin’s Weblogさんのblog Psotによれば

エンバカデロさんは、2009年08月末日にDelphi2006の販売を
停止(ダウンロード販売も停止)するそうです。

2009/07/19 追記
自分のところにもメールがきてました。

2009年7月11日土曜日

HELP UPDATE!!

Delphi2009 と C++ Builder の HELP UPDATE3
がリリースされています。
(日本語のHELPはUPDATE2相当です。)

以下リンク

http://blogs.embarcadero.com/nickhodges/2009/07/10/39253

http://edn.embarcadero.com/jp/article/39661

2009年6月30日火曜日

第13回エンバカデロデベロッパーキャンプ

出席します。(予定)

POKEN持ってますので
よかったらハイタッチ
してやって下さい。

2009年6月24日水曜日

Delphiのクロスプラットフォーム化

こちらのWayne Williams氏へのインタビュー記事によれば
Delphiのクロスプラットフォーム化は、現在の最重要課題との
ことで、来年早々にはお目見えの予定だそうです。

また、この記事ではNative Codeに対するエンバカデロの
考え方についても答えていて、この件については、
マルコ氏もコメント
を出しています。

2009年6月20日土曜日

オンライン販売

Delphi および RadStudioのダウンロード版が

ComponentSource社から発売されることになった。

プレスリリースによると

TeeChart, QuickReport, Develper Express VCL Subxcription
などのコンポーネントがバンドルされた製品も購入可能
のようです。(ComponentSourecさんのサイトでも
購入
が可能になっていました。)

日本で、商用のコンポーネントを買うのは結構大変なので
こういったサービスがあるのは良いよ思う。

また、バンドル版のほうが安いので、ちょっと
お買い得感が出ているかも。

ただ、ComponentSourecさんの説明を良く読むと
コンポーネントを同時に購入しろと書いてあるので、
実際の費用は、

バンドル版 +  コンポーネント

になるみたいですね。

2009年6月15日月曜日

コンポーネント

SourceForge.Netで良さげなコンポーネントを
見つけたのでブックマーク

1つは、TCy components pack for Delphi 7 to 2009
(http://sourceforge.net/projects/tcycomponents/)

結構カラフルなGUI作れそうです。

もう一つは、Delphi2009には対応してないのですが
Alcinoe(http://sourceforge.net/projects/alcinoe/)

のっぺりしたGUIが作れそうなのと、Firebirdの
UDEFがあったりといろいろな機能がありそうです。

2009年6月12日金曜日

Alt + (team)

知っている人は知ってると思うけど
Delphi(Rad Studio)のバージョン画面を開いて
Altキーを押しながらteamと入力すると
制作に関わった方々のクレジットがでます。

ちなみに私は、Stack OverflowのHidden Features of Delphi
知りました。

手元の環境で試したところDelphi7,Delphi2007,Delphi2009は
クレジットが出ました。

あとの環境では確認していないのでクレジットが表示されるか
どうかは不明です。

2009年6月6日土曜日

Bold For Delphi2009

Embarcadero(Codegear)さんがRad Studioで.NETのサポートを
止めたことなどがあってECOがバンドルされなくなった。

で、ECOの代わりにBOLDを統合しようという動きがあるようです。
(元ネタは、Any active Bold for Delphi users ?)

ただ、いろいろあって、作業はしているようなのですが、
実現はまだまだのようです。
(元ネタは、Embarcadero Discussion Forums : Bold for delphi 2009 あたり)
(明示的なロードマップのアナウンスがないためなんとも
言えないのですが・・・)

個人的には、次期Delphiで実現して欲しいと思う。
でもって、プロ版でも使用可能にして頂きたいと思う。

2009年6月5日金曜日

Devgems DataModeler

Devgems DataModelerは、Devgems社から発売されている
DB構築用のツールです。

TMS SoftwareDevgems DataModeler用のライブラリー
リリースされていたのがきっかけで本ツールの存在をしりました。

Devgems社から30日のトライアル版が出ていたので
ちょっと試用してみました。

試用の感想ですが、非常に軽いです。
Firebirdの2に対応していて、
ビジュアルにテーブル・リレーションシップが
作成できるので、ものぐさな自分には有用に
感じました。

値段も99ユーロ(日本円で約15000円)なので
個人的には安いと思います。
(他のERツールが高すぎだと思うのですが・・・(^_^;))

Firebirdの他はSql Serverの2000/2005に
対応しています。

これに、

黒猫SQLStudio,
A5:SQL MK-2

があれば、自分に必要なことのほとんどが
対応可能です。

興味があったら一度試して見て下さい。

2009年6月4日木曜日

2009年5月16日土曜日

Delphiの次期バージョン

現在アメリカで開催中のDelphi liveで次期Versionの概要(実施予定の項目)が
公開されている。

個人的には、DbExpressでのFirebirdのNative Supportに注目

これ、Ent版ではなくPro版で実現されると良いのですが・・・・

2009年4月28日火曜日

Getting Started with Delphi and C++Builder 2009

エンバカデロさんのブログで、Dee Ellingさんから
Getting Started with Delphi and C++Builder 2009の
案内
が出ています。

製本したものは、Lulu.comから購入可能で、PDF版が
ドキュメントサイトからダウンロード可能です。

内容は、初めてRad Studioを使うた人のための
IDEの使い方のガイドとなっています。

HELPはなんだかんだ言って、読み物としては
読みにくいものなので、このようなものがあると
大変助かります。

日本語版も是非欲しいところです。

2009年4月12日日曜日

僕の使っている言語でもできるんです。(その1)

遅ればせながら『More Joel On Software』をよんでいます。

そのなかで、「君のプログラミング言語で、これ、できる?」と
題して、無名関数をあつかっていたのでDelphi2009で書いてみました。
今回はその前半部分です。

話の流れは、『More Joel On Software』を参照にしてください。

まづは、関数を使わない例

0001 program Project1;

0002

0003 {$APPTYPE CONSOLE}

0004

0005 uses

0006   SysUtils;

0007

0008 begin

0009   try

0010   { TODO -oUser -cConsole Main : ここにコードを記述してください }

0011   WriteLn('スパゲッティが食べたい!');

0012   WriteLn('チョコレートムースが食べたい!');

0013   except

0014     on E:Exception do

0015       Writeln(E.Classname, ': ', E.Message);

0016   end;

0017 end.

0018

0019



食べたいが一緒だから関数化して

0001 program Project2;

0002

0003 {$APPTYPE CONSOLE}

0004

0005 uses

0006   SysUtils;

0007

0008 procedure SwedishChef(food : string);

0009 begin

0010   WriteLn(food + 'が食べたい');

0011 end;

0012

0013 begin

0014   try

0015   { TODO -oUser -cConsole Main : ここにコードを記述してください }

0016     SwedishChef('スパゲッティ');

0017     SwedishChef('チョコレートムース');

0018   except

0019     on E:Exception do

0020       Writeln(E.Classname, ': ', E.Message);

0021   end;

0022 end.

0023

0024



ここまでは、今までのDelphiでも可能です。

従来の手続き型で呼び出す関数を切り替えて

0001 program Project3_1;

0002

0003 {$APPTYPE CONSOLE}

0004

0005 uses

0006   SysUtils;

0007

0008 Type

0009   TTakeSometingProc = procedure( S : String);

0010

0011 procedure PutInPot(food : string);

0012 begin

0013   Writeln(food);

0014 end;

0015

0016 procedure BoomBoom(food : string);

0017 begin

0018     Writeln(food);

0019 end;

0020

0021 procedure Cook(food1,food2 : String; aTakeSometingProc : TTakeSometingProc);

0022 begin

0023   Writeln(food1 + 'を取る');

0024   aTakeSometingProc(food1);

0025   aTakeSometingProc(food2);

0026 end;

0027

0028 begin

0029   try

0030   { TODO -oUser -cConsole Main : ここにコードを記述してください }

0031     Cook('ロブスター','水',PutInPot);

0032     Cook('チキン','ココナッツ',BoomBoom);

0033   except

0034     on E:Exception do

0035       Writeln(E.Classname, ': ', E.Message);

0036   end;

0037 end.

0038



これも問題なくうごきます。

手続き型を無名メソッドの宣言に書き換えて

0001 program Project3_2;

0002

0003 {$APPTYPE CONSOLE}

0004

0005 uses

0006   SysUtils;

0007

0008 Type

0009   TTakeSometingProc = reference to procedure ( s : String);

0010

0011

0012 procedure PutInPot(food : string);

0013 begin

0014   Writeln(food);

0015 end;

0016

0017 procedure BoomBoom(food : string);

0018 begin

0019     Writeln(food);

0020 end;

0021

0022 procedure Cook(food1,food2 : String; aTakeSometingProc : TTakeSometingProc);

0023 begin

0024   Writeln(food1 + 'を取る');

0025   aTakeSometingProc(food1);

0026   aTakeSometingProc(food1);

0027 end;

0028

0029 begin

0030   try

0031   { TODO -oUser -cConsole Main : ここにコードを記述してください }

0032     Cook('ロブスター','水',PutInPot);

0033     Cook('チキン','ココナッツ',BoomBoom);

0034   except

0035     on E:Exception do

0036       Writeln(E.Classname, ': ', E.Message);

0037   end;

0038 end.

0039



手続き型の仮引数に対する本引数をコードブロックにすると

0001 program Project4_1;

0002

0003 {$APPTYPE CONSOLE}

0004

0005 uses

0006   SysUtils;

0007

0008 Type

0009   TTakeSometingProc = procedure( S : String);

0010

0011 procedure PutInPot(food : string);

0012 begin

0013   Writeln(food);

0014 end;

0015

0016 procedure BoomBoom(food : string);

0017 begin

0018     Writeln(food);

0019 end;

0020

0021 procedure Cook(food1,food2 : String; aTakeSometingProc : TTakeSometingProc);

0022 begin

0023   Writeln(food1 + 'を取る');

0024   aTakeSometingProc(food1);

0025   aTakeSometingProc(food2);

0026 end;

0027

0028 begin

0029   try

0030   { TODO -oUser -cConsole Main : ここにコードを記述してください }

0031     Cook('ロブスター','水',PutInPot);

0032     Cook('チキン','ココナッツ',BoomBoom);

0033   except

0034     on E:Exception do

0035       Writeln(E.Classname, ': ', E.Message);

0036   end;

0037 end.



これは、コンパイルエラーになります。



無名メソッド型を使えば、コンパイルがとおります。

0001 program Project4_2;

0002

0003 {$APPTYPE CONSOLE}

0004

0005 uses

0006   SysUtils;

0007

0008 Type

0009   TTakeSometingProc = reference to procedure ( s : String);

0010

0011

0012 procedure Cook(food1,food2 : String; aTakeSometingProc : TTakeSometingProc);

0013 begin

0014   Writeln(food1 + 'を取る');

0015   aTakeSometingProc(food1);

0016   aTakeSometingProc(food2);

0017 end;

0018

0019 begin

0020   try

0021   { TODO -oUser -cConsole Main : ここにコードを記述してください }

0022     Cook('ロブスター','水',procedure(food : string)

0023                           begin

0024                             WriteLn(food + 'を鍋に入れる');

0025                           end

0026                           );

0027     Cook('チキン','ココナッツ',procedure(food : string)

0028                             begin

0029                               WriteLn(food + 'を撃つ');

0030                             end

0031                           );

0032   except

0033     on E:Exception do

0034       Writeln(E.Classname, ': ', E.Message);

0035   end;

0036 end.

0037

2009年4月11日土曜日

コンバータ

RemObjects社が、C#のコードをDelphi Prism(Oxygen)のコードに
コンバートするツール
を作ったようです。(最初のバージョンがリリース
されたようです。)

また、SVN Repsostoriesを公開したようです


追伸 Delphi FeedのLookが変わっています。
Stack OverFlowのようなLookになっています。
個人的には、新しいLookは良いと思います。

新書版かペーパバック版が欲しいです。

遅くなりましたがDelphi 2009 Handbook日本語版を
読みました。

この手の本は、実際にコードを打ち込んだり、
サンプルで動作を確認しながら読むのが
筋だと思うが、個人的には通勤電車の中で
読むことが多い。

その時に、気になるのが本の大きさ。
一般的な大きさではありますが、
満員電車のなかでたったまま頁を
送るにはちょっとつらいです。

そこで、値段は同じか高くても良いから
新書版かペーパバック版の
Delphi 2009 Handbookがあったら良いな
と思ったりします。

そもそも、満員電車で読むなと言う話も
ありますので、こんなことを思うのは
自分だけかな?

2009年4月10日金曜日

ほんとかな?

C#の機能に関するブログですが、このブログによれば、

DelphiのほうがVC++より優れているのがMSの公式見解らしいです。

まあ、Delphi2が発売されてからしばらくの間の"凄まじい”ほどの
引き抜き工作を見ればなんとなく明らかなんですが・・・・

こういった、感想をもたれたかたもいるみたいですし
(Action Listはヘジルスバーグさんがいなくなってから
実装された機能)

個人的には、Delphiは過小評価されている製品だと思うので
もっと正当な評価がされるべきだと思う

偶然見つけた記事

2chはあまり詳しくはありませんが

こういった、Delphi製のアプリケーション
大々的に紹介されることは良いことだと思います。

2009年3月19日木曜日

ブログのタイトル変えます。

買収成立時からずっと迷ってけど、日本法人さんも
名実ともにEmbarcaderoさんに変わったようなので
これを気にブログのタイトルを変更致します。

2009年3月13日金曜日

2009年3月5日木曜日

2009年3月4日水曜日

爆速コンパイラ

ブログでは、いろいろ不満も書いていますが

自分がDelphiを使い続ける1番の理由は、
Turbo Pascal からの爆速コンパイラです。

自分がBorland(現Embacadero)のPascal処理系
を本格的に使い出したのはTrubo Pascal 5.5
からです(最初に使ったのは学校のコンピュータ
の授業でのTrubo Pascal3.0)が、それまでは
プログラムを組んだことも無かったので
爆速コンパイラが特別だとは思いませんでした。

その後、会社でN88, MS-C,Turbo-C,など
いろいろな処理系を使いましたが、
これらの処理系を使えば、使うほど
Delphi(Trubo pascal)の爆速コンパイラが
特別であることを実感しました。

エンバカデロオールアクセス

ったった高いです。

378000~って、うちのようなソフトがメインではない
弱小企業では、稟議すら通らないです。(T_T)

このような、大企業様向けのサービスよりも
もっと、個人開発者や、弱小企業にも
優しくして欲しいと思う。

2009年3月3日火曜日

VS2010のFLOATINGサポート

Marco氏のBlogポストによれば、Visual Studio2010のIDEは、
Floating Designerをサポートするとのことだ。

DelphiのIDEでは、Floating Designerが無くなるかもしれないが、
上記のことが今後のIDEのFeatureの方針に何らかの影響を
与えるかも

2009年2月18日水曜日

エンバカデロデベロッパーネットワーク

CDNがEDNに変わっていた。

ログオンしようとすると認証エラーがでるのだけど

これって、自分のPC(FireFox)だけかな?

セキュリティ関係のセミナに行ってきた。

で、思ったのだけど
DelphiというかVCLの脆弱性の話題って
あまり聞いたことがない。

実は、気づかないだけで、Quality Centralには
あがっているのかな?

もしそうであれば、アラートが欲しいものだ。

2009年2月17日火曜日

第12回エンバカデロデブキャンプに行ってきた。

ということで、以下感想および気になったことなどを雑記

・オンデマンドラインセンス

  エンバカデロさんがオンデマンドライセンスを
  始めるとのこと。

  内容は、エンバカデロさんに一定金額払うと
  エンバカデロさんのすべての製品をを使用できるとのこと。

  期間は、明記が無かったがたぶん1年後のと年契約に
  なるのではないかと思う。
 
  1ライセンスあたりの金額は3製品買うとお釣りが
  来るぐらいに設定すると言っていた。
  
  同様なライセンスを持つDelphi PrisimのEnt版3本分で
  考えると50万円前後にになるので、このあたりの
  金額設定ではないかと想像します。

  でも、これがRad Studio Arc版3本分だったら・・・・

  ちょっと怖いです。

・Delphi For PHP

  今回は、開発者のホセさんがスピーカーとして来日て講演
  デモを見る限りでは、使いやすくて拡張しやすそう。
  今のところWEB系をあつかう案件はないのだか、案件が
  来たときには、使用を検討してみよう。
  
  ところで、スピーカさんがデモをやっているのを見ると
  大変簡単に思えるのだが実際やってみるとなかなかできなので
  デモのチュートリアルが欲しいのですが・・・
  
・Delphi for Win32

  DBGRIDの使い方は大変参考になった。
  こういった、ものをまとめたWhite Paperあると良いと
  感じた。
  
・Delphi Prism

  容易に書かれた日本語の情報があまりないので、今回の
  資料は大変有用だと思った。
  
  MSのVC#がMONOをサポートするとは思えないので
  商用でサポートのあるDelphi Prismは大変魅力だ。
  
  Design by Contract周りの機能(Require/Ensure)は
  是非ともDelphi for Win32に入れて欲しい。
  
・トークセッション

  話を聞いていて思ったことは、
  
  どっかで一時期『三昧』になる次期が必要

  作るべきかどうかの判断が重要
  (市場から調達可能であれば逢えてつくる必要はない)
  作るのであれば最後までやりきることが重要
  
  自分はできそうなメドが立ったらできた気になって
  しまうので成長しない(飛躍しない)のだろう(^_^;)
  
  アンケートに対する自分の回答は以下のとおり
  
  0)ビールが好きかSAKEが好きか?
    無回答
    理由)下戸だから
       (今までアルコールをうまいと
       思ったことがない。)
    
  1)初めて使った言語がDelphi? OTHER
    最初にさわったのはSharpのポケコンBASIC
    PCではTurbo Pascal 3.0
    
    ちなみにDelphiを選択した理由は、
    Delphiが日本でのTurbo Pascal 6.0の
    次のVersionだったことです。
    (そこに特にドラマは無いです。)
    
  2)問題が会ったときは自決する? 自決
    ネットでの検索も含めて自決
    理由)Delphiユーザは事務所内で自分だけなので
       聞けない。
       以前、ネットで質問してひどい目にあったのが
       トラウマになりネットでは質問できない。
       (恐れ多くて聞けない。)
       
  3)自分の方法は標準だと思うか?
    思わない。
    理由)標準の定義がよくわからないのと
       他人と比べたことがないので
       
  4)次回のこのセッションはトーク?飲み会?
    トーク
    理由)人見知りがひどいので・・・
       また恐れ多くて発言なんてとてもとても
       
  5)飲み会であれば、会費でも良いか?
    会費がよい。
    理由)もっと他のことにお金をつかって欲しい
    
  6)Delphiのフィールドテストに参加する意志はあるか?
    無い。
    理由)NDAを守れる自信がない
 

2009年1月28日水曜日

コンパイラの将来を読んで思うこと

このポストはあくまでも私見であり、自分な勝手
思い込みで書いてますので、疑いながら
読んでいただければと思います。

CDN上に将来のDelphiコンパイラの概要を
示す論文
がアップされていた。

この論文でNickが言いたかったことは

『中間ファイルを通してフロントエンドと
バックエンドを交換可能な構造にする』

ということではないだろうかと思う。

Nick氏が以前のデベロッパーキャンプで
64bitコンパイラはクロスコンパイラにする
予定だと言っていた。

この64bitコンパイラ作成の作業では、当然の
ことながら、32Bitコンパイラと生成する
機械語を変える必要がある。

この作業の過程でコンパイラのフロントエンド
とバックエンドの切り離しのメドが立ったのでは
ないだろうか?

『中間ファイルを通してフロントエンドと
バックエンドを交換可能な構造にする』

って考え方は.NetのCLRと基本的には
同じだと思う。エンバカデロさんは
これをネイティブで実施しようということ
でしょうか?

Linuxのクロスコンパイラも考えている
ようなことをNickが言っていた記憶が
あるのでWindows64Bitコンパイラを
足ががかりにその他の環境にも手を
広げる予定なのだろうか?

とすれば、Delphi Prismの意味が
なくなってしまうような・・・
(もちろんASP.NETでは意味がありますが・・・)

.NetもWin32 Or Win64 のNativeコンパイラ
を用意する計画があるようなので.Netより
前にしないとインパクトとしてはちょっと
弱くなっちゃうかな?

2009年1月20日火曜日

年貢方式に変えるのかな?

3rd Rail 2.0の日本語版が発売になりました。

でこの製品の売り方がこれまでと変わっていて

一年間限定のライセンスで19,800円となっている。


一年間の間は、常に最新のバージョンにアップする

権利がありるとのことなのだが、使用権については

どうなんだろう?一年毎に更新料がいるのかな?

気になって価格表を確認してみるとDelphi Prismも

同様なライセンスになっている。


ということは、今後、エンバカデロさんは1年間継続

ライセンスに移行するつもりなのだろか?


メーカさんからしてみれば、2~3年に一度

大きなお金が入るよりも年間一定額入るほうが

事業計画が立てやすいと思う。


年間契約がよいか?メジャーバージョン内有効の

契約が良いか?は個人によって判断が分かれる

ところであるとおもうが、それは『中抜けOK』での

話だと思う。


現状のスタンダードサポートのように

『中抜けだめよ!』の契約(中抜けしたときは

中抜け期間分の金額も払わないと更新できない。)

であれば、エンバカデロから年間契約に値する

ロードマップを提供されなければ、使用者にとっての

メリットは少ないと個人的には思う。


今後エンバカデロさんがどのような製品体系(価格体系)

を構成してゆくのかは要経過観察が必要だ。


2009/01/21 追記

藤井さんのブログによれば、3rdRailは、ウィルスバスターと同様な

年貢方式のライセンスのようです。

2009年1月8日木曜日

Delphi 2009 Handbook日本語版

エンバカデロさんで翻訳中です。
実際に出版されるのを楽しみにしよう。
それにしても1週間で半分も訳すなんて
凄過ぎです。