23 - Concepto de métodos

Hasta ahora hemos trabajado con una metodología de programación lineal. Todas las instrucciones de nuestro archivo *.rb se ejecutan en forma secuencial de principio a fin.

Esta forma de organizar un programa solo puede ser llevado a cabo si el mismo es muy pequeño (decenas de líneas)

Cuando los problemas a resolver tienden a ser más grandes la metodología de programación lineal se vuelve ineficiente y compleja.

Si el problema es más complejo buscaremos dividir o descomponer un problema complejo en pequeños problemas. La solución de cada uno de esos pequeños problemas nos trae la solución del problema complejo.

En Ruby el planteo de esas pequeñas soluciones al problema complejo se hace dividiendo el programa en métodos.

Un método es un conjunto de instrucciones en Ruby que resuelven un problema específico.

El lenguaje Ruby ya tiene incorporada algunos métodos básicos. Algunas de ellas ya los utilizamos en conceptos anteriores como son los métodos: print, puts etc.

Veamos ahora como crear nuestros propios métodos.

El tema de métodos en un principio puede presentar dificultades para entenderlo y ver sus ventajas ante la metodología de programación lineal que veníamos trabajando en conceptos anteriores.

Los primeros problemas que presentaremos nos puede parecer que sea más conveniente utilizar programación lineal en vez de la definición de métodos.

A medida que avancemos veremos que si un programa empieza a ser más complejo (cientos de líneas, miles de líneas o más) la división en pequeños métodos nos permitirá tener un programa más ordenado y fácil de entender y por lo tanto en mantener.

Problema 1:

Confeccionar una aplicación que muestre una presentación en pantalla del programa. Solicite la carga de dos valores y nos muestre la suma. Mostrar finalmente un mensaje de despedida del programa.
Implementar estas actividades en tres métodos.

Programa: ejercicio096.py

def presentacion
  puts "Programa que permite cargar dos valores por teclado."
  puts "Efectua la suma de los valores"
  puts "Muestra el resultado de la suma"
  puts "*" * 80
end

def carga_suma
  print "Ingrese el primer valor:"
  valor1 = gets.to_i
  print "Ingrese el segundo valor:"
  valor2 = gets.to_i
  suma = valor1 + valor2
  puts "La suma de los dos valores es: #{suma}"
end

def finalizacion
  puts "*" * 80
  puts "Gracias por utilizar este programa"
end

# bloque principal

presentacion
carga_suma
finalizacion

La forma de organizar nuestro programa cambia en forma radical.

El programa ahora no empieza a ejecutarse en la línea 1.

El programa comienza a ejecutarse luego del comentario "# bloque principal":

# bloque principal

presentacion
carga_suma
finalizacion

Primero declaramos los tres métodos llamados presentacion, carga_suma y finalizacion.

La sintaxis para declarar un método es mediante la palabra clave def seguida por el nombre del método (el nombre del método no puede tener espacios en blanco, comenzar con un número o en mayúsculas )

Todo el bloque del método se indenta dos espacios como venimos trabajando cuando definimos estructuras condicionales o repetitivas.

Dentro de un método implementamos el algoritmo que pretendemos que resuelva ese método, por ejemplo el método presentacion tiene por objetivo mostrar en pantalla el proposito del programa:

 
def presentacion
  puts "Programa que permite cargar dos valores por teclado."
  puts "Efectua la suma de los valores"
  puts "Muestra el resultado de la suma"
  puts "*" * 80
end

El método carga_suma permite ingresar dos enteros por teclado, sumarlos y mostrarlos en pantalla:

def carga_suma
  print "Ingrese el primer valor:"
  valor1 = gets.to_i
  print "Ingrese el segundo valor:"
  valor2 = gets.to_i
  suma = valor1 + valor2
  puts "La suma de los dos valores es: #{suma}"
end

El método finalizacion tiene por objetivo mostrar un mensaje que informe al operador que el programa finalizó:

    
def finalizacion
  puts "*" * 80
  puts "Gracias por utilizar este programa"
end

Para mostrar 80 asteriscos lo más fácil es multiplicar un String con el caracter asterisco por el número 80.

Luego de definir los métodos tenemos al final de nuestro archivo *.rb las llamadas a los métodos:

# bloque principal

presentacion
carga_suma
finalizacion

Los métodos es obligatorio que se encuentren declarados previos al bloque principal.

Si no hacemos las llamadas a los métodos los algoritmos que implementan nunca se ejecutarán.

Cuando en el bloque del programa principal se llama un método hasta que no finalice no continua con la llamada al siguiente método:

# bloque principal

presentacion  # se ejecutan las cuatro líneas que contiene el método presentacion y recién continúa con la próxima línea.

métodos en Ruby

El orden en que llamamos a los métodos es muy importante. Supongamos que nuestro bloque del programa principal llamamos los métodos en este orden:

# bloque principal

finalizacion
carga_suma
presentacion

Veremos que primero muestra el mensaje de finalización, luego la carga y suma de datos y finalmente aparece por pantalla los mensajes de presentación de nuestro programa.

Yo se que en principio al ser un problema tan sencillo y que venimos de resolver muchos programas con la metodología de programación lineal nos parecer mas fácil implementar este programa con la sintaxis:

puts "Programa que permite cargar dos valores por teclado."
puts "Efectua la suma de los valores"
puts "Muestra el resultado de la suma"
puts "*" * 80
print "Ingrese el primer valor:"
valor1 = gets.to_i
print "Ingrese el segundo valor:"
valor2 = gets.to_i
suma = valor1 + valor2
puts "La suma de los dos valores es: #{suma}"
puts "*" * 80
puts "Gracias por utilizar este programa"

Tengamos un poco de paciencia para aprender la nueva sintaxis de dividir un programa en métodos, imagina que las soluciones a problemas complejos pueden requerir miles de líneas y un planteo secuencial será muy difícil de mantener.

Problema 2:

Confeccionar una aplicación que solicite la carga de dos valores enteros y muestre su suma.
Repetir la carga e impresión de la suma 5 veces.
Mostrar una línea separadora después de cada vez que cargamos dos valores y su suma.

Programa: ejercicio097.rb

def carga_suma
  print "Ingrese el primer valor:"
  valor1 = gets.to_i
  print "Ingrese el segundo valor:"
  valor2 = gets.to_i
  suma = valor1 + valor2
  puts "La suma de los dos valores es: #{suma}"
end  

def separacion
  puts "*" * 80
end

# bloque principal
for x in 1..5
  carga_suma
  separacion
end

métodos en Ruby

Hemos declarado dos métodos, una que permite cargar dos enteros sumarlos y mostrar el resultado:

def carga_suma
  print "Ingrese el primer valor:"
  valor1 = gets.to_i
  print "Ingrese el segundo valor:"
  valor2 = gets.to_i
  suma = valor1 + valor2
  puts "La suma de los dos valores es: #{suma}"
end  

Y otro método que tiene por objetivo mostrar una línea separadora con asteriscos:

def separacion
  puts "*" * 80
end

Ahora nuestro bloque principal del programa, recordemos que estas líneas son las primeras que se ejecutarán cuando iniciemos el programa:

# bloque principal
for x in 1..5
  carga_suma
  separacion
end

Como vemos podemos llamar al método carga_suma y separación muchas veces en nuestro caso en particular 5 veces.

Lo nuevo que debe quedar claro es que la llamada a los métodos desde el bloque principal de nuestro programa puede hacerse múltiples veces (esto es lógico, recordemos que puts es un método ya creada en Ruby y lo llamamos múltiples veces dentro de nuestro algoritmo)

En el bloque principal utilizamos el ciclo repetitivo for donde x toma los valores de 1 a 5 de uno en uno (La sintaxis 1..5 es un rango en Ruby)

Problemas propuestos

  • Desarrollar un programa con dos métodos. El primero solicite el ingreso de un entero y muestre el cuadrado de dicho valor. El segundo que solicite la carga de dos valores y muestre el producto de los mismos. Llamar desde el bloque principal a ambos métodos.
  • Desarrollar un programa que solicite la carga de tres valores y muestre el menor. Desde el bloque principal del programa llamar 2 veces a dicho método (sin utilizar una estructura repetitiva)
Solución
ejercicio098.rb

def calcular_cuadrado
  print "Ingrese un entero:"
  valor = gets.to_i
  cuadrado = valor * valor
  puts "El cuadrado es #{cuadrado}"
end

def calcular_producto
  print "Ingrese primer valor:"
  valor1 = gets.to_i
  print "Ingrese segundo valor:"
  valor2 = gets.to_i
  producto = valor1 * valor2
  puts "El producto de los valores es: #{producto}"
end

# bloque principal

calcular_cuadrado
calcular_producto




ejercicio099.rb

def menor_valor
  print "Ingrese primer valor:"
  valor1 = gets.to_i
  print "Ingrese segundo valor:"
  valor2 = gets.to_i
  print "Ingrese tercer valor:"
  valor3 = gets.to_i
  print "Menor de los tres:"
  if valor1<valor2 && valor1<valor3
    puts valor1
  else
    if valor2<valor3
      puts valor2
    else
      puts valor3
    end
  end
end

# bloque principal

menor_valor
menor_valor