前田です。 In message "[ruby-list:6089] Re: Ruby連載 第3回" Yukihiro Matsumoto <matz / netlab.co.jp> wrote: |まず,Rubyに関数ポインタがないのはSmalltalk的とでもいうよう |な古典的オブジェクト指向モデルを採用しているからです.この辺 |は関数ポインタをベースにしているオブジェクト指向モデルの |Pythonとは大きく違うところです.どっちが良いかと言うのは主観 |ですが. | |そういうモデルなので,単純には「関数ポインタを渡せば良いや」 |で済まなかったのが,第1の理由です.なんらかの方法で関数ポイ |ンタに当たるものを生成できないといけないわけです. | |で,Smalltalkでは「ブロックオブジェクトを引数にする」という |方法を選び,Rubyでは「イテレータブロックを暗黙の引数にする」 |という方法を選んだわけです. 実はこの間Javaオブジェクトを操作するためだけに作った インタープリタでは、実装の簡単さのために(^^;)Python とSmalltalkの折衷案みたいにしてしまいました。 def collect(elements, func): result = #[]; for i in elements: result << func(i); end; return result; end; v = #["foo", "bar", "baz"]; v2 = collect(v, [ str: str.toUpperCase(); ]); あるいは、 def func(str): return str.toUpperCase(); end; v2 = collect(v, func); でもこうするためには変数と関数で名前空間を共有させないと いけないのですよね...。 Javaはメソッドとフィールドに同じ名前を使えるので、関数は オブジェクトだけどメソッドはオブジェクトではない、という 中途半端な実装になってしまいました。 | * forが実装しやすい | | とっつきやすさのためfor文が欲しかったのですが,ブロック | を渡すというセマンティックスではちょっと意味的に??な部 | 分が出て来ます. forはEnumeration(外部イテレータ)を使うためのシンタックスシュガー にしました。 keys = hash.keys(); while keys.hasMoreElements() println(keys.nextElement()); end; の代りに、 for i in hash.keys(): println(i); end; と。 でも、Javaで外部イテレータを採用していたのでこうしたわけ ですが、外部イテレータって定義するのが面倒ですしRubyには 合いませんよね。 # 速度も外部イテレータの方が遅そうですし。 -- 前田 修吾