rails - ¿Sin parámetros nombrados en Ruby?
ruby o php (4)
Aunque los parámetros nombrados no son compatibles con el lenguaje Ruby, puede simularlos pasando los argumentos de su función a través de un hash. Por ejemplo:
def meth(id, parameters = {})
options = parameters["options"] || "options"
scope = parameters["scope"] || "scope"
puts options
end
Que se puede usar de la siguiente manera:
meth(1, scope: "meh")
Su código existente simplemente asigna un valor variable, luego pasa esa variable a su función. Para obtener más información, consulte: http://deepfall.blogspot.com/2008/08/named-parameters-in-ruby.html .
Esto es tan simple que no puedo creer que me haya atrapado.
def meth(id, options = "options", scope = "scope")
puts options
end
meth(1, scope = "meh")
-> "meh"
Tiendo a usar hashes para las opciones de argumento solo porque así fue como lo hizo la manada, y está bastante limpio. Pensé que era el estándar. Hoy, después de aproximadamente 3 horas de búsqueda de errores, he rastreado un error de esta gema que estoy usando y que asume que los parámetros con nombre serán respetados. Ellos no son.
Entonces, mi pregunta es esta: ¿El parámetro nombrado oficialmente no se respeta en Ruby (1.9.3), o es este un efecto secundario de algo que me falta? Si no lo son, ¿por qué no?
Creo que dos cosas están sucediendo aquí:
- Está definiendo un parámetro en el método llamado ''alcance'' con un valor predeterminado de "alcance"
- Cuando llama al método, está asignando el valor "meh" a una nueva variable local llamada ''scope'', que no está relacionada con el nombre del parámetro en el método que está llamando.
Lo que está sucediendo en realidad:
# 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"
No hay soporte * para los parámetros con nombre (ver a continuación la actualización 2.0). Lo que está viendo es solo el resultado de asignar "meh"
al scope
se pasa como el valor de las options
en meth
. El valor de esa tarea, por supuesto, es "meh"
.
Hay varias formas de hacerlo:
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"
Y así. Sin embargo, son soluciones alternativas por la falta de parámetros nombrados.
Editar (15 de febrero de 2013):
* Bueno, al menos hasta el próximo Ruby 2.0 , que admite argumentos de palabras clave. Al momento de escribir esto, está en el lanzamiento del candidato 2, el último antes del lanzamiento oficial. Aunque deberá conocer los métodos anteriores para trabajar con 1.8.7, 1.9.3, etc., los que pueden trabajar con versiones más nuevas ahora tienen la siguiente opción:
def meth(id, options: "options", scope: "scope")
puts options
end
meth 1, scope: "meh"
# => "options"
Ruby no tiene parámetros nombrados.
La definición de método de ejemplo tiene parámetros con valores predeterminados.
El ejemplo del sitio de llamada asigna un valor a la variable local de ámbito de la persona que llama con el nombre de ámbito y luego pasa su valor (meh) al parámetro de opciones .