Módulo 5-6: Funciones y Métodos
Crear código reutilizable y modular
⚙️ Módulo 5-6: Funciones y Métodos
Duración: Semanas 5 y 6
Objetivos del Módulo
- Entender qué son los métodos y por qué son importantes
- Aprender a definir métodos con y sin parámetros
- Dominar el concepto de scope (alcance) de variables
- Trabajar con blocks, procs y lambdas
- Crear código reutilizable y modular
Contenido Teórico
1. ¿Qué son los Métodos?
Los métodos son bloques de código reutilizable que realizan una tarea específica. Nos permiten:
- Evitar repetir código
- Organizar mejor nuestros programas
- Hacer el código más legible y mantenible
2. Definición Básica de Métodos
# Método sin parámetros
def greet
puts "¡Hola!"
end
# Llamar al método
greet # Output: ¡Hola!
# Método con parámetros
def greet_person(name)
puts "¡Hola #{name}!"
end
greet_person("Ana") # Output: ¡Hola Ana!
3. Métodos con Valores de Retorno
# Ruby devuelve automáticamente la última expresión
def add(a, b)
a + b
end
result = add(5, 3)
puts result # Output: 8
# Return explícito
def is_even(number)
return true if number % 2 == 0
false
end
puts is_even(4) # Output: true
puts is_even(5) # Output: false
4. Parámetros y Argumentos
Parámetros Obligatorios
def introduce(name, age)
"Me llamo #{name} y tengo #{age} años"
end
puts introduce("Luis", 25)
Parámetros Opcionales (con valores por defecto)
def greet(name, greeting = "Hola")
"#{greeting}, #{name}!"
end
puts greet("María") # "Hola, María!"
puts greet("María", "Buenos días") # "Buenos días, María!"
Parámetros con Nombre (keyword arguments)
def create_user(name:, age:, city: "No especificada")
"Usuario: #{name}, #{age} años, vive en #{city}"
end
puts create_user(name: "Ana", age: 30)
puts create_user(name: "Luis", age: 25, city: "Madrid")
Número Variable de Parámetros (splat operator)
def add_all(*numbers)
numbers.sum
end
puts add_all(1, 2, 3) # 6
puts add_all(1, 2, 3, 4, 5) # 15
# Con argumentos con nombre
def process_data(action, **options)
puts "Acción: #{action}"
options.each { |key, value| puts "#{key}: #{value}" }
end
process_data("guardar", formato: "json", compresion: true)
5. Scope (Alcance) de Variables
Variables Locales
def example_method
local_variable = "Solo existe aquí"
puts local_variable
end
example_method
# puts local_variable # Error: variable no definida
Variables de Instancia
@instance_variable = "Disponible en toda la instancia"
def show_variable
puts @instance_variable
end
show_variable # Output: Disponible en toda la instancia
Variables Globales
$global_variable = "Disponible en todo el programa"
def show_global
puts $global_variable
end
show_global # Output: Disponible en todo el programa
6. Blocks (Bloques)
Los blocks son fragmentos de código que se pueden pasar a métodos:
# Block con each
[1, 2, 3].each { |number| puts number * 2 }
# Block multilinea
[1, 2, 3].each do |number|
square = number ** 2
puts "#{number} al cuadrado es #{square}"
end
# Métodos que reciben blocks
def execute_three_times
yield if block_given?
yield if block_given?
yield if block_given?
end
execute_three_times { puts "¡Hola!" }
Métodos que usan blocks
def process_numbers(numbers)
result = []
numbers.each do |number|
result << yield(number) if block_given?
end
result
end
numbers = [1, 2, 3, 4, 5]
squares = process_numbers(numbers) { |n| n ** 2 }
puts squares # [1, 4, 9, 16, 25]
7. Procs y Lambdas
Procs
# Crear un proc
my_proc = Proc.new { |x| x * 2 }
# Usar el proc
puts my_proc.call(5) # 10
# Pasar proc a un método
numbers = [1, 2, 3, 4, 5]
result = numbers.map(&my_proc)
puts result # [2, 4, 6, 8, 10]
Lambdas
# Crear un lambda
my_lambda = lambda { |x| x * 3 }
# o usando la sintaxis corta
my_lambda = ->(x) { x * 3 }
puts my_lambda.call(4) # 12
# Los lambdas son más estrictos con argumentos
add = ->(a, b) { a + b }
puts add.call(2, 3) # 5
Diferencias entre Procs y Lambdas
# Lambdas verifican el número de argumentos
my_lambda = ->(x, y) { x + y }
# my_lambda.call(1) # Error: argumentos incorrectos
# Procs son más flexibles
my_proc = Proc.new { |x, y| (x || 0) + (y || 0) }
puts my_proc.call(1) # 1 (y es nil, se convierte a 0)
8. Métodos Útiles de Ruby
Métodos de Enumerable
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# select - filtrar elementos
even_numbers = numbers.select { |n| n.even? }
puts even_numbers # [2, 4, 6, 8, 10]
# map - transformar elementos
squares = numbers.map { |n| n ** 2 }
puts squares # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# reduce - combinar elementos
sum = numbers.reduce(0) { |accumulated, n| accumulated + n }
puts sum # 55
# find - encontrar primer elemento que cumple condición
first_greater_than_5 = numbers.find { |n| n > 5 }
puts first_greater_than_5 # 6
9. Métodos Predicate (Predicado)
Por convención, los métodos que devuelven true/false terminan en ?:
def positive?(number)
number > 0
end
def empty?(array)
array.empty?
end
puts positive?(5) # true
puts positive?(-3) # false
puts empty?([]) # true
puts empty?([1, 2]) # false
10. Métodos de Bang (!)
Los métodos que terminan en ! suelen modificar el objeto original:
def uppercase!(text)
text.upcase!
end
name = "juan"
uppercase!(name)
puts name # "JUAN" (modificado)
# Comparar con versión sin !
def uppercase(text)
text.upcase
end
name2 = "ana"
result = uppercase(name2)
puts name2 # "ana" (sin cambios)
puts result # "ANA" (nuevo string)
Ejercicios Prácticos
Ve al archivo ejercicios.rb para practicar los conceptos aprendidos.
Proyecto del Módulo
Ve al archivo proyecto_sistema_inventario.rb para completar el proyecto de este módulo.