2004-04-09 (Fri) [長年日記]
_ 「自衛隊は即時撤退しても日米同盟は壊れません」
リンクはJMMの冷泉彰彦氏の記事だが、 すぐに他の記事に変わってしまうと思う。*1 (前はバックナンバーが公開されてたような気がするんだけど。)
おおまかな論旨としては、
- もちろん人質の命は大切だが、撤退しない場合のリスクはそれ以外にもある。 日米同盟への影響は、撤退しない場合の方が深刻になる可能性がある。
- この事件がなくとも、昨今の治安情勢からこれ以上の自衛隊の活動は難しい。 今撤退したとしても、テロに屈したと考える必要はない。
といったように、自衛隊の撤退を主張している。 意見にはおおむね賛成 *2 なんだけど、
これに対しては、日本は堂々と自衛隊を引くべきです。胸を張って引き上げるべきです。アメリカの庶民は、誰も不思議に思わないでしょうし、大した悪感情も持たないでしょう。政治家のメンツは潰れます。ブッシュ=チェイニー=ラムズフェルドのメンツは潰れます。小泉=福田=石破のメンツは潰れるでしょう。ですが、それだけです、日米関係はビクともしないでしょう。
[「自衛隊は即時撤退しても日米同盟は壊れません」from 911/USAより引用]
この政治家のメンツが問題だよな。 皮肉なことに、福田さんは「人命は地球より重い」発言の福田赳夫元首相の息子ときている。
と思ったら、 父の時と「時代が違う」 だそうだ。
_ 3人の誘拐について大急ぎで
こちらは池澤夏樹氏のメールマガジンの記事(あ、Movable Typeなんだ)。 議論の流れはぜんぜん違うけど、結論は同じ。
ただし、3人が誘拐されたから、その生命を救うために撤退するのではない。それでは取引になってしまう。 今後、日本に対して何か強い要求を持つ者に対して、日本の民間人を誘拐すれば目的はかなうという前例を与えることになる。それこそテロに屈することになる。
そうではなくて、自衛隊を復興支援という名目のもとに派遣したことが間違いであったことを公式に認め、今のイラクを平和に導くために必要なのは武力ではないことを認め、その上で撤退を速やかに実行する。言い換えれば、誘拐とは無関係に、政策の転換を内外にはっきり表明する。
[3人の誘拐について大急ぎでより引用]
本当にそうできれば、と思います。
_ selector namespace
[ruby-list:39453]を見て思ったけど、やっぱりRuby2には selector namespaceが欲しいな。
簡単に復習すると、selector namespaceというのは、特定のスコープ においてのみ既存のクラスのインスタンスの振舞いを変えることが出来る仕組みである。
たとえば、
namespace mathematical class Fixnum def /(other) return Rational(self, other) end end end
みたいなselector namespace定義(?)があったとして、これを
import mathematical
のように特定のスコープ(たぶんファイルとかクラス・モジュールとか)にインポートすると、 そのスコープでのみ、
p 1 / 2 # => 1/2(Rational)
のようにFixnum#/の挙動が変わるわけだ。
この時、namespaceをimportするスコープが静的であるのがミソで、このスコープから メソッド呼び出しを行った場合、呼び出し先のFixnumの挙動には影響しないのだ。 *1
*1 動的なスコープでよければ、[RAA:scope-in-state]で同じようなことを実現できる。
_ selector namespaceとdouble dispatch
selector namespaceがあればこんなこともできる。たとえば、
class HTMLElement ... def print_on(output) ... case output when String ... when IO ... end ... end ... end
というコードがあったとしよう。
これはよくないコードだ。 なぜならオブジェクトのクラスを調べて分岐しているから。 こういうコードを書くと、outputにStringやIO以外の新しいクラス(たとえば、 IOと同じようなメソッドを提供するけれどもIOを継承していないようなクラス) のインスタンスを受け取ることができなくなってしまう。
より良いのは、こんなコードだ。
class String def print_part_of_html_element(element) ... end end class IO def print_part_of_html_element(element) ... end end class HTMLElement ... def print_on(output) ... output.print_part_of_html_element(self) ... end ... end
こうしておくと、新しいクラスのインスタンスをHTMLElement#print_onに渡したければ、 そのクラスにprint_part_of_html_elementというメソッドを定義すればよいわけだ (polymorphism万歳)。 *1
ところが、このコードにも問題がある。 それは組み込みクラスの挙動をグローバルに変更してしまっている点だ。 こんなことをするのはあまり気持ちのいいものではないし、何より、 他の人が同じようなことをしていたらメソッド名が衝突してしまうかもしれない。
そこで、selector namespaceの出番だ。
namespace html_element_printing class String def print_part_of_html_element(element) ... end end class IO def print_part_of_html_element(element) ... end end end
のようにnamespaceを定義しておいて、
class HTMLElement import html_element_printing ... def print_on(output) ... output.print_part_of_html_element(self) ... end ... end
のようにimportしてやればいい。 これなら、HTMLElementの外にはまったく影響がないのだ。 何て素晴らしいんだろう。
*1 こういうのをdouble dispatchという。 print_onとprint_part_of_html_elementの二回method dispatchをするから。 CLOSみたいにmulti methodならこんなことをしなくてもよいのだが、Rubyが そうなることはないだろう。まつもとさんはmulti methodが嫌いらしいから。 selector namespaceにもそういう面があるけど、オブジェクトとメソッドの結び付きが弱く なるんだよね。
_ selector namespaceと継承
もちろん、まったく問題がないわけではない。 一番大きいのは継承との整合性の問題だろう。
たとえば、[ruby-list:39453]を例にあげると、
namespace mathematical class Integer def /(other) return Rational(self, other) end end end import mathematical p 1 / 2
とした時に、出力は1/2(Rational)になるべきだろうか、それとも0になるべきだろうか。
知っての通り1はFixnumのインスタンスで、FixnumはIntegerのサブクラスだ。 /はIntegerではなくFixnumに定義されているので、普通はIntegerに/を定義しても Fixnumの挙動は変わらない。
問題は、selector namespaceの定義とどちらを優先するかだ。 場合によってはselector namespaceの定義の方を優先してほしい場合が あるかもしれないが、そうした場合、サブクラス化によるpolymorphismの恩恵を 受けることができなくなってしまう。 やっぱりサブクラスの定義を優先するべきなのかもしれない。
_ selector namespaceの実装
もう一つの大きな問題はどうやって効率的に実装するかということ。
これに関しては、selector namespaceをimportしているスコープのメソッド呼び出しの うち、selector namespaceで定義されたメソッドの呼び出しかもしれない部分(メソッド名 を見ればわかる)だけ、メソッド検索のアルゴリズムを変えてしまうのはどうだろう。
たとえば、前にささださんが日記で(メソッド検索全般の話として)書いてたと思うけど、 メソッド名毎にクラス(や特異クラス)をキーにしたテーブルを作っておくとか。 テーブルのメンテナンスが大変そうだとか、特異メソッドを多用してたら大変という のはあるかもしれない *1 けれど、selector namespaceを使わない場合の性能が落ちなければ許容できるような気がする。
*1 selector namespace使ってるところで特異メソッドは使わない気がするけど。
_ selector namespaceって名前でいいのか?
あと、selector namespaceって名前はどうなんだろう。 たぶん、Smalltalkのselectorのことだよね。 Ruby的にはmethod namespaceとかの方がわかりやすい?