Rubyのキーワード引数にやられた話
今週もRubyネタです。
引数に与えるパラメータを名前指定で与える、いわゆるキーワード引数を実現したかったのですが、そこに大きな勘違いが潜んでおり、一見すると意図通りに見えるコードが、Rubyの解釈では意図と大きく異なっているという状況が生まれてしまった話です。
もともとPythonやらCで鳴らしてきた私としては、Rubyでもこんな風に書いていました。
code:ruby
def test_func(a = 10, b = 20)
end
一見すると、正しく動いているので意図したとおりのコードになっているように見えます。
でも、実はメソッドの定義にも、呼出の形にも意図とは異なる解釈がうまれます。
その挙動について、次のPythonで書いたコードとRubyで書いたコードを比べてみると、違いがよくわかります。
code:ruby
def test_func(a = 10, b = 20)
end
code:python
def test_func(a = 10, b = 20):
Rubyのコードは、変数名を指定しても指定した変数に値が渡されていません。
それもそのはず、実はこのコード、引数を渡すそのタイミングでローカル変数が作られているだけで、変数名をキーワードに指定して値を渡したことにはなっていないのです。
つまり、こんなコードと同じです。
code:ruby
def test_func(a = 10, b = 20)
end
b = 200
a = 100
Rubyでキーワードを指定して値を渡すためには次のようにします。
code:ruby
def test_func(a: 10, b: 20)
end
でも、これは位置を取る形で変数を渡しても機能しません。
code:ruby
p test_func(100, 200) #=> !!ERROR!! Pythonでは同じコードで動かすことができますが、Rubyではそれができません。
この辺ハマりどころだと思うんですが、あんまりネット上に情報がなくて少し困りました。