34

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

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

meth(1, scope = "meh")

-> "meh"

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

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

4

4 に答える 4

39

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

# 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"です。もちろん、その割り当ての値はです。scopeoptionsmeth"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.0までは!この記事を書いている時点では、公式リリースの最後のリリース候補2にあります。1.8.7、1.9.3などで動作するには、上記の方法を知っている必要がありますが、新しいバージョンで動作できるようになったものには、次のオプションがあります。

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

meth 1, scope: "meh"
# => "options"
于 2012-03-08T04:32:14.080 に答える
5

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

  1. デフォルト値「scope」で「scope」という名前のメソッドにパラメーターを定義しています
  2. メソッドを呼び出すと、値「meh」が「scope」という名前の新しいローカル変数に割り当てられます。これは、呼び出しているメソッドのパラメーター名とは無関係です。
于 2012-03-08T03:35:18.020 に答える
3

名前付きパラメーターは Ruby 言語ではサポートされていませんが、ハッシュを介して関数の引数を渡すことでそれらをシミュレートできます。例えば:

def meth(id, parameters = {})
  options = parameters["options"] || "options"
  scope = parameters["scope"] || "scope"

  puts options
end

次のように使用できます。

meth(1, scope: "meh")

既存のコードは単に変数を割り当て、その変数を関数に渡します。詳細については、http: //deepfall.blogspot.com/2008/08/named-parameters-in-ruby.htmlを参照してください。

于 2012-03-08T04:01:57.840 に答える
0

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

メソッド定義の例には、デフォルト値を持つパラメーターがあります。

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

于 2012-03-08T03:35:15.227 に答える