「すべてがFになる」読了
- 作者: 森博嗣
- 出版社/メーカー: 講談社
- 発売日: 1998/12/11
- メディア: 文庫
- 購入: 16人 クリック: 241回
- この商品を含むブログ (586件) を見る
いきなりネタバレですが、タイトルのFは16進数のFです。すべてがFってのはFFF・・・みたいな。
そうそう。現在僕が開発に携わってるシステムでも、FFFFFFが意味持ってます。だってアセンブラにバイナリファイルなんだもん。DBなんてものは無かったのさ(いや、あっただろうけど、当時はまだ実用じゃなかったってのが正しいのか?)ちなみに携わってるだけで、開発はしてません。ていうか出来ないし。興味もほとんどないし。
さて本書。いきなり天才プログラマが出てきます。3巻で天才数学者ってのも出てきますが、天才プログラマの方が上だな。名前も真賀田 四季(まがた しき)ってのがいいね。
プログラマとして惹かれたのは、本書中に出てくる環境レッドマジック。
開発環境がものすごく充実しているのよ。ここだけのシステムだわ。これを一度経験したら、他のところでは働けない。
って、どんなシステムよ!経験してー。
実はこのレッドマジックは、天才プログラマが作ったもので、建物の入退室管理やら、電話やら、色々制御しているんですが、物語のキーにもなっていたりします。ソフトウェア業界に関わっている人なら、読んで見ると面白いかも。
そういえば、僕が読んだ小説で、○○な人なら面白いかも。って結構書いたような記憶があるんですが、○○に「ソフトウェア業界に関わっている人」なんて書く日が来るとは思いませんでした。
ところで、冒頭で「オブジェクト指向システム設計入門」という本の引用が載ってます。
どんなもんかとAmazonで調べてみたら、書評を見た感じでは、なんだかぱっとしない本みたい。
1993年の本だし古いかなー。丸善に寄ったときは見てみよう。
デリゲート
プログラミングC# p286
12章から「デリゲートとイベント」ということで、C#のウリの一つ(?)であるデリゲートの説明になるわけですが、のっけから、
例えば州知事が亡くなった場合、
とか不吉な出だしになってます。
イベント処理で使うのだということはなんとなく分かるのですが、こまごました説明を読んでも良く分からないので、12.1に書いてある
を元にサンプルを書いてみる。
実は、先日書いた関数を関数に渡す@C言語のエントリは、このコメントから着想しています。
で、サンプル。
using System; class FunctionPointer { public delegate int twoitem(int a, int b); public static int add(int a, int b) { return a + b; } public static int sub(int a, int b) { return a - b; } static void Main(string[] args) { // 関数ポインタを定義 FunctionPointer.twoitem fp; fp = new FunctionPointer.twoitem(FunctionPointer.add); Console.WriteLine("result = {0}", fp(5, 3)); fp = new FunctionPointer.twoitem(FunctionPointer.sub); Console.WriteLine("result = {0}", fp(5, 3)); } }
結果はこう。
result = 8 result = 2
delegateっちゅうのは、要はメソッド自体の入れ物で、カッコ付ければコールできると。まあそんな感じでしょう。
Java的にはインタフェース使って書くようなところでしょう。
それはこんな感じ。
public class FunctionPointer { public static void main(String[] args) { TwoItem ti = new Add(); System.out.println("result = " + ti.twoitem(5, 3)); ti = new Sub(); System.out.println("result = " + ti.twoitem(5, 3)); } } interface TwoItem { public int twoitem(int a, int b); } class Add implements TwoItem { public int twoitem(int a, int b) { return a + b; } } class Sub implements TwoItem { public int twoitem(int a, int b) { return a - b; } }
結果は同じ。
result = 8 result = 2
C#で書いても似たようなものだと思います。インタフェースでなくデリゲートな理由は、p287にもあるように、
というわけで、interfaceとか、その実装classとかを用意しなくても、少ないコード量で多態性を実現できる仕組みと捕らえるのが良いようです。
マルチキャストデリゲート
プログラミングC# p297
デリゲートに複数のメソッドを登録すると、順番に呼んでくれます。
using System; class MulticastFunctionPointer { public delegate void hello(); public static void hello_Japanese() { Console.WriteLine("こんにちは"); } public static void hello_English() { Console.WriteLine("hello"); } public static void hello_Spanish() { Console.WriteLine("HOLA!"); } static void Main(string[] args) { // 関数ポインタを定義 MulticastFunctionPointer.hello fp; fp = new MulticastFunctionPointer.hello(MulticastFunctionPointer .hello_Japanese); fp += new MulticastFunctionPointer.hello(MulticastFunctionPointe r.hello_English); fp += new MulticastFunctionPointer.hello(MulticastFunctionPointe r.hello_Spanish); fp(); } }
+=で連結しているのがミソですね。ちなみに結果はこう。
こんにちは hello HOLA!
なんだか、JavaScriptのaddEventListenerみたいな感じ。
<html> <head> <script language = "JavaScript"> function aaa() { alert("aaa"); } function bbb() { alert("bbb"); } function OnLoad() { document.form1.button1.addEventListener("click", aaa, true); document.form1.button1.addEventListener("click", bbb, true); } </script> </head> <body onLoad = "OnLoad()"> <form name = "form1"> <input type = "button" name = "button1" value = "押して"> </form> </body> </html>
ボタン押すと、関数aaaと関数bbbが両方実行されます。
このサンプルの方が、よっぽどマルチキャストデリゲートを説明してるな。。
匿名メソッド
プログラミングC# p315
Javaでいう匿名クラスみたいなものか?
using System; class FunctionPointer { public delegate int twoitem(int a, int b); public static int add(int a, int b) { return a + b; } public static int sub(int a, int b) { return a - b; } static void Main(string[] args) { // 関数ポインタを定義 FunctionPointer.twoitem fp; fp = FunctionPointer.add; Console.WriteLine("result = {0}", fp(5, 3)); fp = FunctionPointer.sub; Console.WriteLine("result = {0}", fp(5, 3)); fp = delegate(int a, int b) { return a * b; }; Console.WriteLine("result = {0}", fp(5, 3)); } }
結果はこう。
result = 8 result = 2 result = 15
multメソッドを用意しなくても、いきなりコードブロックで掛け算の処理がかけるってわけです。
ちなみに、さっきのJavaの例を無名クラスで同じように拡張するとこんな感じ。
public class FunctionPointer3 { public static void main(String[] args) { TwoItem ti = new Add(); System.out.println("result = " + ti.twoitem(5, 3)); ti = new Sub(); System.out.println("result = " + ti.twoitem(5, 3)); ti = new TwoItem() { public int twoitem(int a, int b) { return a * b; } }; System.out.println("result = " + ti.twoitem(5, 3)); } } interface TwoItem { public int twoitem(int a, int b); } class Add implements TwoItem { public int twoitem(int a, int b) { return a + b; } } class Sub implements TwoItem { public int twoitem(int a, int b) { return a - b; } }
もちろん結果はこう。
result = 8 result = 2 result = 15
五線譜記法とか欲しいね。
結構大変かな?結構大変だろうなぁ。