Funciones y pase de argumentos en Ruby
Una de las características más importantes de las funciones es la capacidad que tienen de recibir argumentos…. ¿o parámetros? ¿cómo es la cosa? Empecemos por ahí, la diferencia entre un parámetro y un argumento en una función.
1 def add_two(number)
2 number + 2
3 end
4
5 add_two(3)
=> 5
En la linea 1 vemos la definición de la función con el nombre add_two
la función también define un parámetro, quiere decir que cualquier valor que le pasemos a la función estará guardado dentro de nuestro parámetro number.
Este parámetro number está siendo usando dentro de la función como una variable que podemos operar, como se observa en la linea 2, simplemente agregamos o sumamos 2 al valor guardado dentro de number.
En la linea 5, podemos observar la que invocamos nuestra función add_two
pero además le pasamos como argumento el numero 3. Al final el resultado de ejecutar esta función es sumar 3 + 2
como resultado la función retorna 5.
Aquí radica la diferencia entre un parámetro y un argumento, cuando estamos creando nuestra función definimos parámetros y cuando estamos llamando una función le pasamos argumentos.
Proceso de transformación de la materia prima
Los argumentos son como la materia prima de las funciones, las cuales procesarán estos materiales y darán como resultado un producto final. En ruby tenemos multiples formas de definir nuestros parámetros en las funciones, veamos uno a uno los tipos de parámetros que podemos definir y aprendamos sus diferencias:
Argumento requerido (required argument)
def paint_text(text, color)
# coolz stuff
end
Hasta ahora esta es la forma más fácil de pase de argumentos, lo llamamos argumentos requerido porque si una función no recibe todos los argumentos no puede ser ejecutada.
Argumento opcionales (optional argument)
def paint_text(text, color = "black")
# the same things above
end
Como podemos observar nuestra función paint_text
recibe el argumento text
es decir el texto que vamos a pintar y a continuación podemos obviar el argumento color
ya que en la función nuestro parámetro color
tiene un valor negro por defecto.
¿Qué pasaría si pasamos los dos argumentos?
paint_text("¡Hola vale!", "red")
¡Justo como lo pensaste!, el segundo argumento sobre escribe el valor por defecto definido en el parámetro color
de la función.
Hash como argumento
Podemos usar un hash argumento para pasar distintas opciones a nuestra función, veamos el siguiente ejemplo:
def draw_point(options = {})
x = options.fetch(:x)
y = options.fetch(:y)
# other cool stuff
end
La función draw_point
recibe un hash de las siguientes formas:
# Hash explicito como argumento
draw_point({ x: 1, y: 2})# Hash implícito como argumento
draw_point(x: 2, y: 5)# Hash almacenado en una variable sin importar su orden y pasado como argumento.
coord = { y: 10, x: 20 }
draw_point(coord)
Todos las formas de pasar los argumentos como un hash son equivalentes, quedará a gusto del consumidor cual usar.
Argumento palabra clave (Keyword Argument)
Las funciones con parámetros definidos como keyword reciben como argumento un hash implícito, explicito o una variable que contenga un hash. Una de las ventajas de usar esta forma de definición de parámetros es que nuestro condigo es más explicativo al momento de ser usado, ya que cada argumento tiene una llave que lo identifica.
def draw_point(x:, y:)
# No need .fetch to do cool stuff
end
*Splat Argument
El argumento *splat
nos permite pasar un array de valores implícito o explicito a una función, veamos un ejemplo:
def players(*names)
puts names
end
players('fulano', 'mengano')
=> fulano
=> menganoplayers(['fulano', 'mengano', 'sultano'])
=> fulano
=> mengano
=> sultano
**Splat Argument
El argumento **splat
nos permite pasar un hash como un contenedor flexible, veamos un ejemplo:
def players(**data)
data.each do |name, position|
puts "Player: #{name}, Position: #{position}"
enddata = {
"Altuve": "2nd Base",
"Alex Bregman": "3rd Base",
"Evan Gattis": "Catcher",
"George Springer": "OF"
}players(data)
=> Player: Altuve, Position: 2nd Base
=> Player: Alex Bregman, Position: 3rd Base
=> Player: Evan Gattis, Position: Catcher
=> Player: George Springer, Position: OF
¡Todos juntos!
Todos estos tipos de parámetros pueden pasarse como argumento en la misma función, pero deben de hacerse en un orden especifico para evitar errores de sintaxis:
def testing(a, b = 1, *c, d: 1, **x)
puts a, b, c, d, x
endtesting('a', 'b', 'c', 'd', 'e', d: 2, x: 1)
=> a
=> b
=> c
=> d
=> e
=> 2
=> {:x=>1}
¡Hemos aprendido sobre los poderosos argumentos de los métodos de Ruby y cómo usarlos! Los argumentos requeridos son un buen comienzo, entonces puedes agregar flexibilidad con argumentos opcionales y agregar claridad con argumentos keyword.