web-dev-qa-db-ja.com

Rubyに名前付きパラメーターはありませんか?

これはとても単純なので、私を捕まえたとは信じられません。

def meth(id, options = "options", scope = "scope")
  puts options
end

meth(1, scope = "meh")

-> "meh"

群れがそれを行った方法であるという理由だけで、引数オプションにハッシュを使用する傾向があります-そしてそれは非常にきれいです。それが標準だと思いました。今日、約3時間のバグハンティングの後、私はたまたま使用しているこのgemにエラーを突き止めました仮定名前付きパラメーターが尊重されます。ではない。

それで、私の質問はこれです:名前付きパラメーターはRuby(1.9.3)で公式に尊重されていませんか、それとも私が見逃しているものの副作用ですか?いいえ、なぜですか?

32
JohnMetta

実際に何が起こっているのか:

# 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に割り当ててoptionsmeth値として渡された結果です。もちろん、その割り当ての値は"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"

等々。ただし、名前付きパラメーターがないため、これらはすべて回避策です。


編集(2013年2月15日):

*ええと、 少なくとも次のRuby 2. まで、キーワード引数をサポートします!これを書いている時点では、公式リリースの最後のリリース候補2にあります。 1.8.7、1.9.3などで動作するには、上記の方法を知っている必要があります。新しいバージョンで動作できるものには、次のオプションがあります。

def meth(id, options: "options", scope: "scope")
  puts options
end

meth 1, scope: "meh"
# => "options"
38
brymck

私はここで2つのことが起こっていると思います:

  1. デフォルト値「scope」を使用して、「scope」という名前のメソッドでパラメーターを定義しています。
  2. メソッドを呼び出すときは、値「meh」を「scope」という名前の新しいlocal変数に割り当てます。これは、呼び出すメソッドのパラメーター名とは関係ありません。
5
Jon M

Rubyには名前付きパラメーターがありません。

サンプルのメソッド定義には、デフォルト値のパラメーターがあります。

呼び出しサイトの例では、scopeという名前の呼び出し元のスコープのローカル変数に値を割り当ててから、その値(meh)optionsパラメーターに渡します。

0
DigitalRoss