これはとても単純なので、私を捕まえたとは信じられません。
def meth(id, options = "options", scope = "scope")
puts options
end
meth(1, scope = "meh")
-> "meh"
群れがそれを行った方法であるという理由だけで、引数オプションにハッシュを使用する傾向があります-そしてそれは非常にきれいです。それが標準だと思いました。今日、約3時間のバグハンティングの後、私はたまたま使用しているこのgemにエラーを突き止めました仮定名前付きパラメーターが尊重されます。ではない。
それで、私の質問はこれです:名前付きパラメーターはRuby(1.9.3)で公式に尊重されていませんか、それとも私が見逃しているものの副作用ですか?いいえ、なぜですか?
実際に何が起こっているのか:
# Assign a value of "meh" to scope, which is OUTSIDE meth and equivalent to
# scope = "meth"
# meth(1, scope)
meth(1, scope = "meh")
# Ruby takes the return value of assignment to scope, which is "meh"
# If you were to run `puts scope` at this point you would get "meh"
meth(1, "meh")
# id = 1, options = "meh", scope = "scope"
puts options
# => "meh"
名前付きパラメーターのサポート*はありません(2.0の更新については以下を参照してください)。表示されているのは、"meh"
をscope
に割り当ててoptions
のmeth
値として渡された結果です。もちろん、その割り当ての値は"meh"
です。
それを行うにはいくつかの方法があります。
def meth(id, opts = {})
# Method 1
options = opts[:options] || "options"
scope = opts[:scope] || "scope"
# Method 2
opts = { :options => "options", :scope => "scope" }.merge(opts)
# Method 3, for setting instance variables
opts.each do |key, value|
instance_variable_set "@#{key}", value
# or, if you have setter methods
send "#{key}=", value
end
@options ||= "options"
@scope ||= "scope"
end
# Then you can call it with either of these:
meth 1, :scope => "meh"
meth 1, scope: "meh"
等々。ただし、名前付きパラメーターがないため、これらはすべて回避策です。
*ええと、 少なくとも次のRuby 2. まで、キーワード引数をサポートします!これを書いている時点では、公式リリースの最後のリリース候補2にあります。 1.8.7、1.9.3などで動作するには、上記の方法を知っている必要があります。新しいバージョンで動作できるものには、次のオプションがあります。
def meth(id, options: "options", scope: "scope")
puts options
end
meth 1, scope: "meh"
# => "options"
私はここで2つのことが起こっていると思います:
Rubyには名前付きパラメーターがありません。
サンプルのメソッド定義には、デフォルト値のパラメーターがあります。
呼び出しサイトの例では、scopeという名前の呼び出し元のスコープのローカル変数に値を割り当ててから、その値(meh)をoptionsパラメーターに渡します。