Escribiendo nuestros propios métodos en Ruby

Vamos a ver cómo podemos escribir nuestros propios métodos en Ruby con ayuda de un programa simple: p008mismetodos.rb. Observa que usamos def y end para declarar un método. Los parámetros son simplemente una lista de variables locales entre paréntesis.

No es necesario declarar los valores que debe regresar un método: siempre regresa el valor de su última línea. Es recomendable dejar una línea en blanco entre cada nueva definición de un método. Según una de las convenciones de Ruby, los métodos deben llevar sus parámetros entre paréntesis. Sin embargo, como puts, p y gets son usados con mucha frecuencia, la regla de los paréntesis no aplica. En rails vas a encontrar llamadas a métodos con los parámetros sin paréntesis.

 1 # Un método regresa el valor de su última línea.
 2 # Métodos que regresan verdadero o falso, con frecuencia
 3 # tienen el caracter ? como sufijo.
 4 # Los métodos que son "peligrosos" o que modifican al receptor
 5 # es posible que tengan el caracter ! como sufijo (métodos Bang)
 6 # Un metodo simple:
 7 
 8 def hola
 9   puts 'Hola'
10 end
11 
12 #para usar el método
13 hola
14 
15 # Un método con un argumento (1)
16 def hola1(nombre)
17   puts 'Hola ' + nombre
18   return 'exito'
19 end
20 
21 puts(hola1('juan'))
22 
23 # Method with an argument (2)
24 def hola2 nombre2
25   puts 'Hola ' + nombre2
26   return 'exito'
27 end
28 puts(hola2 'alvarez')

El resultado de ejecutar este programa es1:

Mis Metodos

Ruby te permite especificar los valores por defecto para los argumentos de un método que serán utilizados si el código que llama al método no los especifica explícitamente. Esto se logra utilizando el operador de asignación. Observa el ejemplo p009mismetodos1.rb:

 1 # la inerpolacion es el proceso de insertar el resultado de una
 2 # expresion en una cadena.
 3 # el operador de interpolacion #{...} es evaluado por separado
 4 
 5 def mtd(arg1="Dibya", arg2="Shashank", arg3="Shashank")
 6   "#{arg1}, #{arg2}, #{arg3}."
 7 end
 8 puts mtd
 9 puts mtd("ruby")

El resultado es:

Mis Metodos1

En el programa anterior el operador de interpolación #{...} es calculado por separado y el resultado es anexado automáticamente a la cadena. Cuando ejecutas estas líneas, el operador #{...} no está visible en la pantalla, en su lugar vemos el resultado de calcular o evaluar lo que se encuentra dentro del operador.

Nota: Interpolación se refiere al proceso de insertar el resultado de una expresión dentro de una cadena de caracteres. La manera para lograr la interpolación dentro de una cadena es colocar la expresión dentro del símbolo #{}. Por ejemplo:

1 puts "100 * 5 = #{100 * 5}"

da como resultado:

100 * 5 = 500

La expresión {100 * 5} interpola el resultado de multiplicar 100×5 en la misma posición.

El ejemplo p010aliasmtd nos muestra cómo crear un alias para un método.

 1 # alias nombre_nuevo nombre_original
 2 # Cuando creamos un alias para un metodo, el nuevo nombre
 3 # hace referencia a una copia del cuerpo del metodo original
 4 
 5 def metodo_original
 6   "metodo original"
 7 end
 8 
 9 alias metodo_nuevo metodo_original
10 
11 def metodo_original
12   "metodo original mejorado"
13 end
14 puts metodo_original
15 puts metodo_nuevo

El resultado es:

Alias Methods

¿Ruby nos permite escribir funciones que puedan aceptar un número variable de parámetros? Si, observa el ejemplo p011vararg.rb

 1 # Ejemplo de metoda con numero variable de argumentos
 2 # El asterisco toma todas los argumentos que son enviados al metodo 
 3 # y los asigna a un array llamado mi_cadena como se muestra en el ejemplo
 4 # El do end es un bloque de Ruby y vamas a hablar de ellos mas adelante
 5 
 6 def foo(*mi_cadena) 
 7   mi_cadena.each do |palabra| 
 8     puts palabra 
 9   end 
10 end 
11 foo('hola','mundo') 
12 foo()

Como puedes ver, al hacer uso de un asterisco, es posible incluso pasar cero argumentos. El código mostrado arriba da como resultado las palabras ‘hola’ y ‘mundo’ escritas en línas consecutivas cuando se llama el método con los argumentos hola y mundo y no da como resultado nada cuando se llama el mismo método sin argumentos:

Variable Arguments

Si quieres incluír argumentos opcionales (*x) deben aparecer después de los argumentos no opcionales:

1 def args_opc(a, b, *x) #correcto
2 
3 def args_opc(a, *x, b) #incorrecto

¿Cuál es el límite máximo de parámetros que podemos pasar a un método en Ruby? No existe un límite de parámetros.

¿Cuál es la secuencia en que los parámetros son puestos en la pila de objetos, de izquierda a derecha como en C, o de derecha a izquierda como en Pasacal? La respuesta es de izquierda a derecha como puedes ver en el siguiente ejemplo:

1 # La secuencia en que los parametros son puestos en la pila es de izquierda a  derecha
2 def mtd(a=99, b=a+1)
3   [a,b]
4 end
5 puts mtd

Los métodos son pasados por valor o por referencia? Da una mirada a este post y observa el siguiente ejemplo:

1 def downer(cadena)
2   cadena.downcase!
3 end
4 
5 a = "HOLA"
6 downer(a)
7 puts a

Métodos Bang (!)

Los métodos que modifican a un objeto y terminan en un signo de admiración (!) son conocidos como métodos “bang”. Por costumbre, el signo de admiración etiqueta a los métodos como peligrosos, específicamente, como el equivalente “peligroso” de un método con el mismo nombre pero sin el signo.

Vas a encontrar varios pares de métodos, uno con signo y otro sin signo de admiración. Los que no contienen signo de admiración ejecutan una acción y regresan una copia del objeto. La versión del mismo método con signo de interrogación transforman el objeto original.

Como ejemplo de dichos pares de métodos tenemos sort/sort! para arrays, upcase/upcase! y chomp/chomp! para las cadenas y reverse/reverse! para las cadenas y arrays. cadenas. En cualquier caso, si llamas el método sin !, obtienes un nuevo objeto. Si llamas el método con !, vas a efectuar una operación en el mismo objeto al cual le enviaste el mensaje.

1Yo no estoy utilizando SciTE para ejecutar los ejemplos. La imagen que ves aquí es el resultado de ejecutar el programa en mac OSX a través de Textmate. De cualquier manera, no es importante en qué plataforma trabajes o qué editor de textos uses sino el resultado que arroja Ruby y éste es el mismo en Windows, Linux o mac OSX.