Los parámetros nombrados en Ruby no funcionan?

Me pregunto por qué los parámetros nombrados no funcionan como espero.

def my_method(var1, var2 = 1, var3 = 10) puts var1, var2, var3 end my_method(999, var3 = 123) 

La salida

 999 123 10 

En lugar de (al menos, como creo que debería ser):

 999 1 123 

Entonces, ¿qué debo hacer para usar los parámetros nombrados?

PD: cuando uso el hash, no es lo que estoy buscando todavía:

 def my_method(var1, vars = {var2: 1, var3: 10} ) puts var1, vars[:var2], vars[:var3] end my_method(999, var3: 123) 999 123 my_method(999, var2: 111, var3: 123) 999 111 123 my_method(999) 999 1 10 

Así que tengo que anular cada valor de vars o no anularlos en absoluto. ¿Hay alguna forma más conveniente?

En ruby my_method(999, var3 = 123) significa, asigne a var3 el valor 123 y páselo a my_method .

No hay un concepto de parámetros nombrados, sin embargo, puede usar un hash como argumento para mi my_method , como:

 def my_method(args = {}) p "#{args[:a]}, #{args[:b]}, #{args[:c]}" end 

Entonces puedes llamarlo con:

 my_method(b: 2, c: 3, a: 1) 

que imprimirá 1, 2, 3 , porque b: 2, c: 3, a: 1 se infiere que es un hachís por Ruby. Puedes indicar explícitamente el hash también con:

 my_method({b: 2, c: 3, a: 1}) 

Como se señaló, Ruby no tiene argumentos de palabras clave (aún así, están llegando en 2.0). Para lograr lo que estás tratando de hacer, un hash de options es un lenguaje muy común en Ruby.

 def my_method(var1, options = {}) var2 = options.fetch(:var2, 1) var3 = options.fetch(:var3, 10) puts var1, var2, var3 end my_method(999) # => 999, 1, 10 my_method(999, var3: 123) # => 999, 1, 123 my_method(999, var2: 111) # => 999, 111, 10 my_method(999, var2: 111, var3: 123) # => 999, 111, 123 my_method() # => ArgumentError: wrong number of arguments (0 for 1) 

Tenga en cuenta que al usar options.fetch(:key, default) lugar de options[:key] || default options[:key] || default es frecuentemente preferible porque le permite especificar explícitamente valores false (es decir, false y nil ).

 options = {x: nil, y: false} x = options[:x] || 42 # sets x to 42 x = options.fetch(:x, 42) # sets x to nil y = options[:y] || 43 # sets y to 43 y = options.fetch(:y, 43) # sets y to false z = options[:z] || 44 # sets z to 44 z = options.fetch(:z, 44) # sets z to 44 

Incluso puede pasar un bloque para fetch que le permite diferir el cálculo del valor predeterminado:

 options.fetch(:x) { some_expensive_calculation } # some_expensive_calculation is only called if necessary 

Puedes usar esto

  def my_method(options = {}) puts options[:var1] || '' puts options[:var2] || '' puts options[:var3] || '' end 

llamada usando

 my_method(var1:999, var3: 123) 

o

 my_method(var1:999) 

También puedes jugar con algo como esto:

 def method(data) defaults = {var2: 1, var3: 10} (@var1, @var2, @var3) = defaults.merge(data).values_at(:var1, :var2, :var3) p @var1, @var2, @var3 end method(var1: 999, var3: 123) 

Se lanzó Ruby 2.0.0 , ahora puede usar parámetros nombrados.

 def my_method(var1, var2: 1, var3: 10) puts var1, var2, var3 end my_method(999, var3: 123) 

El resultado:

 999 1 123 

O otro ejemplo:

 def foo(str: "foo", num: 100) [str, num] end p foo(str: 'buz', num: 1) #=> ['buz', 1] p foo(str: 'bar') # => ['bar', 100] p foo(num: 2) # => ["foo", 2] p foo # => ['foo', 100] p foo(bar: 'buz') # => ArgumentError