Ответ 1
Что на самом деле происходит:
# 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"
И так далее. Тем не менее, все они обходятся обходными способами, поскольку отсутствуют именованные параметры.
Изменить (15 февраля 2013 г.):
* Ну, по крайней мере до предстоящего 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"