注意。このエントリはRuby 2.0に入るかもしれない機能について述べていますが、本機能が本当に2.0に採用されるかどうかは、未定です。
Rubyではメソッド定義のdefの中でdefを書くことができるが、 実際にはメソッド定義が遅延されるだけで、あまり役に立たない。
その理由については 原くんのHotlinkインタビューを見てもらうと良いと思う。
まつもと たとえばネストしたメソッドになにか意味をつけるとしたら、それは多分、そのスコープでだけ有効なメソッドを導入するっていうことだよね。
yhara 「ネストしたメソッド」になってしまうんですね。「ネストした関数」でなくて。
まつもと うん、まあ「ネストした関数」でもいいんだけど、でも Ruby にいま「関数」は無い。
yhara 無いですね。
まつもと だから、「関数」って言う新しいものを導入するって形になってしまう、のかな?
yhara 「ネストしたメソッド」っていうのは、なんか不自然な雰囲気がしますね。
まつもと メソッドの中で def を定義した時に何が定義されるかって言う時に、もしそれがメソッドであるとすれば、どっかのオブジェクトに属してないとダメだよね。で、そのスコープにいる時だけ存在するメソッドって何なんだろうって。
ささだ Argument オブジェクトとか作ってとかなんとか、ってなるかもしれませんね。
まつもと でもそれレシーバじゃないからね。「レシーバを省略すると self に行く」っていうルールと違うものを導入しないといけないことになるんだよね。
yhara すごく納得したのでもういいです。僕はもうその主張はしないことにします。
で、それに対するひとつのアイディアとして、「レシーバに対する特異メソッドを定義する」というものを考えていた。
最近思いついた、もうひとつ別のアイディアとして、「ネストしたメソッド定義は関数定義」にするというのもはどうだろうか、と考えた。
具体的には
def foo def bar(*args) ... end bar(1) end
をコンパイル時に
def foo bar = ->(*args) do ... end bar.call(1) end
と展開するというものだ。ローカル変数としてのbarにアクセスできるかどうかは未定だけど、 barは「関数」を引数なしで呼び出すことにするのか、lambdaが入っている リードオンリーの変数とするかどちらかだとと思う。
基本的にコンパイル時の問題なので、実装はさほど難しくないと思う。
ただし、問題(デメリット)もあって、十分な議論なしで安易に導入すべきではないとも思う。
やっぱ、導入は難しいかな。