method - Parámetros nombrados en Ruby 2
ruby hash parameters method (8)
A partir de Ruby 2.1.0 , ya no tendrá que establecer valores predeterminados para los parámetros con nombre. Si omite el valor predeterminado para un parámetro, la persona que llama deberá proporcionarlo.
def concatenate(val1: ''default'', val2:)
"#{val1} #{val2}"
end
concatenate(val2: ''argument'')
#=> "default argument"
concatenate(val1: ''change'')
#=> ArgumentError: missing keyword: val2
Dado:
def test1(var1="default value123")
var1
end
def test2(var1:"default value123")
var1
end
Se comportarán de la misma manera cuando no pasen una discusión:
test1
#=> "default value123"
test2
#=> "default value123"
Pero se comportarán de manera muy diferente cuando se aprueba un argumento:
test1("something else")
#=> "something else"
test2("something else")
#=> ArgumentError: wrong number of arguments (1 for 0)
test1(var1: "something else")
#=> {:var1=>"something else"}
test2(var1: "something else")
#=> "something else"
No entiendo completamente cómo funcionan los parámetros nombrados en Ruby 2.0.
def test(var1, var2, var3)
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) #wrong number of arguments (1 for 3) (ArgumentError)
se trata como un hash. Y es muy divertido porque para usar parámetros con nombre en Ruby 2.0 debo establecer valores predeterminados para ellos:
def test(var1: "var1", var2: "var2", var3: "var3")
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) # ok => 1111 2222 var3-new
que es muy similar al comportamiento que Ruby tenía antes con los valores predeterminados de los parámetros:
def test(var1="var1", var2="var2", var3="var3")
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) # ok but ... {:var3=>"var3-new", :var1=>1111, :var2=>2222} var2 var3
Sé por qué está sucediendo eso y casi cómo funciona.
Pero solo tengo curiosidad, ¿ debo usar valores predeterminados para los parámetros si uso parámetros con nombre?
Y, ¿alguien puede decirme cuál es la diferencia entre estos dos, entonces?
def test1(var1="default value123")
#.......
end
def test1(var1:"default value123")
#.......
end
Creo que la respuesta a su pregunta actualizada se puede explicar con ejemplos explícitos. En el ejemplo siguiente, tiene parámetros opcionales en un orden explícito:
def show_name_and_address(name="Someone", address="Somewhere")
puts "#{name}, #{address}"
end
show_name_and_address
#=> ''Someone, Somewhere''
show_name_and_address(''Andy'')
#=> ''Andy, Somewhere''
El enfoque del parámetro nombrado es diferente. Todavía le permite proporcionar los valores predeterminados, pero le permite a la persona que llama determinar cuáles parámetros, si corresponde, debe proporcionar:
def show_name_and_address(name: "Someone", address: "Somewhere")
puts "#{name}, #{address}"
end
show_name_and_address
#=> ''Someone, Somewhere''
show_name_and_address(name: ''Andy'')
#=> ''Andy, Somewhere''
show_name_and_address(address: ''USA'')
#=> ''Someone, USA''
Si bien es cierto que los dos enfoques son similares cuando se proporcionan sin parámetros, difieren cuando el usuario proporciona parámetros para el método. Con parámetros nombrados, la persona que llama puede especificar qué parámetro se proporciona. Específicamente, el último ejemplo (que proporciona solo la dirección) no es del todo alcanzable en el primer ejemplo; puede obtener resultados similares SÓLO al suministrar AMBOS parámetros al método. Esto hace que los parámetros nombrados sean mucho más flexibles.
En primer lugar, el último ejemplo que publicó es engañoso. Estoy totalmente en desacuerdo con que el comportamiento sea similar al anterior. ¡El último ejemplo pasa el argumento hash in como el primer parámetro opcional que es una cosa diferente!
Si no desea tener un valor predeterminado, puede usar nil
.
Si desea leer una buena reseña, consulte " Argumentos de palabras clave de Ruby 2 ".
Esto está presente en todas las otras respuestas, pero quiero extraer esta esencia.
Hay cuatro tipos de parámetros:
Required Optional
Positional | def PR(a) | def PO(a=1) |
Keyword | def KR(a:) | def KO(a:1) |
Al definir una función, los argumentos posicionales se especifican antes de los argumentos clave, y los argumentos requeridos antes de los opcionales.
irb(main):006:0> def argtest(a,b=2,c:,d:4)
irb(main):007:1> p [a,b,c,d]
irb(main):008:1> end
=> :argtest
irb(main):009:0> argtest(1,c: 3)
=> [1, 2, 3, 4]
irb(main):010:0> argtest(1,20,c: 3,d: 40)
=> [1, 20, 3, 40]
editar: el argumento de palabra clave requerido (sin un valor predeterminado) es nuevo a partir de Ruby 2.1.0, como lo mencionaron otros.
Estoy de acuerdo contigo en que es extraño exigir valores predeterminados como el precio por usar parámetros nombrados, y evidentemente los mantenedores de Ruby están de acuerdo con nosotros. Ruby 2.1 eliminará el requisito de valor predeterminado a partir de 2.1.0-preview1 .
Puede definir parámetros con nombre como
def test(var1: var1, var2: var2, var3: var3)
puts "#{var1} #{var2} #{var3}"
end
Si no pasa uno de los parámetros, Ruby se quejará de una undefined local variable or method
.
Según " blog.marc-andre.ca/2013/02/23/ruby-2-by-example ", debe tener los valores predeterminados:
En Ruby 2.0.0, los argumentos de la palabra clave deben tener valores predeterminados, o bien deben ser capturados por ** extra al final.
def test(a = 1, b: 2, c: 3)
p [a,b,c]
end
test #=> [1,2,3]
test 10 #=> [10,2,3]
test c:30 #=> [1,2,30] <- this is where named parameters become handy.
Puede definir el valor predeterminado y el nombre del parámetro y luego llamar al método como lo haría si tuviera parámetros "con nombre" basados en hash pero sin la necesidad de definir valores predeterminados en su método.
Necesitarías esto en tu método para cada "parámetro nombrado" si estuvieras usando un hash.
b = options_hash[:b] || 2
como en:
def test(a = 1, options_hash)
b = options_hash[:b] || 2
c = options_hash[:c] || 3
p [a,b,c]
end