そのなかで、「君のプログラミング言語で、これ、できる?」と
題して、無名関数をあつかっていたので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
0 件のコメント:
コメントを投稿