ささだです。
「Ruby2.0 引数、変数まわりの仕様について」
yarv-dev という ML で、まつもとさんに Ruby2.0 の仕様について伺ったので、
どうせなのでまとめてみました。知っている人にはいまさらそんなの、という内
容かもしれませんが、私のような知らなかった人にはそれなりに面白い資料にな
るんじゃないでしょうか。これで議論が少しでも活発になるとうれしいです。
(最近、ruby-dev summary に載せるネタがなくてさびしいって話もありますし)
発端は、
http://www dot atdot dot net/~ko1/w3ml/w3ml.cgi/yarv-dev/msg/15
からの一連のスレッドです。
(crawler避けです、ご容赦ください)
(matz) という文字で始まる段落は、まつもとさんの発言をそのままコピーして
います。
------------------------------------------------------------------------
= ブロックローカル変数について
== ローカル変数は原則的にメソッドローカル
== ブロックパラメータはブロックローカル
== 重複は許さない
i=1
iter{|i|
...
}
はエラー。
= 引数について
== Values オブジェクトの導入
(matz)現状の多重代入は複雑怪奇なルールですが、新しいものは
* return, yieldなどに複数の値を渡すとValuesオブジェクトを
作る。
* 複数の左辺値はValuesオブジェクトの各要素と対応する。
というルールになります。現状ではlambdaで作ったProcオブジェクトは引数の個
数チェックが厳しいというルールになっていますが、lambdaを予約語にして
Proc(or Block)とLambdaを別クラスにしようかと思っています。(/matz)
def m
yield([1,2])
end
m{|i,j|
p i,j #=> 1,2
}
は obsolete、次のようにする。
def m
yield(*[1,2]) # Values(1,2) ということになるのかな?
end
== ブロック引数にキーワード引数を許すか
(matz)気持ちとしてはlamdaを予約語にしてlambdaのパラメータだけキーワード
引数やブロック引数を受け付けるようにしたいのですが、define_methodのよう
なメソッドのためには普通のブロックパラメータにもこれらを含みたいんですよ
ね。悩んでます。
(無理やりブロック構造をメソッドにマッピングするようなことはやらない)
== yield や Proc#call にブロックを渡すことを許すか
(matz)許そうと思っています。
= キーワード引数について
(matz) 評価順序は基本的に左から右、上から下です。
文法は
定義側
def foo(a, b=15, *rest, c:val, **krest)
...
end
呼び出し側
foo(1, 2, 4, *ary, c:44, k:42, **hash)
# 利用例
def m(a, b, k:10, **kargs)
p k
p kargs[:hoge]
end
kargs は Hashそのまま。つまり、以下のように利用可能。
hash = {:k1 => 1, :k2 => 2, ...}
m(**hash)
(でも、
def m(hash={...}, **kargs)
...
end
hash = {:k1 => 1, :k2 => 2, ...}
m(**hash)
では、どっちにどっちがくるんだかわかんなくなるような)
まんま Hash なので、kargs[:hoge](引数としてわたってこな
かったもの)は nil を返す。
(ko1)また、proxy オブジェクト作るときとかの method_missing は、
def method_missing *args, **kargs
...
someobj.send *args, **kargs # (A)
end
になるんですか?
(matz) そうなりますねえ。言われてみれば面倒ですね。
--
// SASADA Koichi at atdot dot net
//
----
宣伝:
yarv-dev は YARV: Yet Another Ruby VM 開発用MLで、quickml です。
興味のある方は yarv-dev at quickml dot atdot dot net へ、
ko1 at atdot dot net をCcにして例のごとくご参加ください。