Metodos, Bloques y Procs
## Objetivos de Aprendizaje
- Definir y llamar metodos
- Comprender parametros de metodos y valores de retorno
- Trabajar con bloques y yield
- Dominar procs y lambdas
- Comprender closures y alcance
## Metodos
### Sintaxis Basica
```ruby
def saludar
"Hola!"
end
puts saludar # "Hola!"
```
### Metodo con Parametros
```ruby
def saludar(nombre)
"Hola, #{nombre}!"
end
puts saludar("Alicia") # "Hola, Alicia!"
```
### Parametros por Defecto
```ruby
def saludar(nombre = "Mundo")
"Hola, #{nombre}!"
end
puts saludar # "Hola, Mundo!"
puts saludar("Bob") # "Hola, Bob!"
```
### Multiples Parametros
```ruby
def sumar(a, b)
a + b
end
puts sumar(2, 3) # 5
```
### Operador Splat
```ruby
def sumar(*numeros)
numeros.reduce(0, :+)
end
puts sumar(1, 2, 3, 4, 5) # 15
```
### Argumentos de Palabra Clave (Ruby 2.0+)
```ruby
def crear_usuario(nombre:, email:, edad: 18)
{ nombre: nombre, email: email, edad: edad }
end
crear_usuario(nombre: "Alicia", email: "alice@ejemplo.com")
crear_usuario(nombre: "Bob", email: "bob@ejemplo.com", edad: 25)
```
### Doble Splat para Argumentos de Palabra Clave
```ruby
def config(**opciones)
opciones
end
config(servidor: "localhost", puerto: 3000, depuracion: true)
# => { servidor: "localhost", puerto: 3000, depuracion: true }
```
## Valores de Retorno
```ruby
# Retorno explicito
def encontrar_primer_par(numeros)
numeros.each { |n| return n if n.even? }
nil
end
# Retorno implicito (ultima expresion)
def sumar(a, b)
a + b
end
```
## Nombres de Metodos
```ruby
# Metodos de pregunta (?) - retornan booleano
def vacio?(str)
str.length == 0
end
# Metodos bang (!) - potencialmente peligrosos
def ordenar!(array)
array.sort!
end
def ordenar(array)
array.sort
end
# Metodos setter
def nombre=(valor)
@nombre = valor
end
# Predicados
def entre?(a, b)
self >= a && self <= b
end
```
## Argumentos Variables
```ruby
def registrador(nivel, *mensajes)
mensajes.each { |msg| puts "[#{nivel.upcase}] #{msg}" }
end
registrador("INFO", "Servidor iniciado", "Usuario conectado", "Solicitud procesada")
```
## Bloques
### Sintaxis de Bloques
```ruby
# Bloque do-end
[1, 2, 3].each do |n|
puts n
end
# Bloque con llaves
[1, 2, 3].each { |n| puts n }
```
### Yield
```ruby
def repetir(veces)
veces.times { yield }
end
repetir(3) { puts "Hola" }
# Salida: Hola tres veces
```
### Yield con Argumentos
```ruby
def calcular(a, b)
yield(a, b)
end
resultado = calcular(5, 3) { |x, y| x + y }
puts resultado # 8
resultado = calcular(5, 3) { |x, y| x * y }
puts resultado # 15
```
### Block_given?
```ruby
def tal_vez_repetir(veces)
if block_given?
veces.times { yield }
else
puts "No se proporciono bloque"
end
end
tal_vez_repetir(3) { puts "Hola" }
tal_vez_repetir(3)
```
## Procs
### Crear Procs
```ruby
# Proc.new
saludar = Proc.new { |nombre| "Hola, #{nombre}!" }
# metodo proc
gritar = proc { |texto| texto.upcase }
# palabra clave lambda (stabby lambda)
bienvenida = lambda { |nombre| "Bienvenido, #{nombre}!" }
# Forma abreviada stabby lambda (Ruby 1.9+)
despedida = ->(nombre) { "Adios, #{nombre}!" }
```
### Llamar Procs
```ruby
saludar = proc { |nombre| "Hola, #{nombre}!" }
puts saludar.call("Alicia")
puts saludar["Bob"] # Sintaxis alternativa
puts saludar.("Charlie") # Sintaxis alternativa
```
### Proc vs Lambda
```ruby
# Proc - no verifica el numero de argumentos
p = proc { |a, b| "#{a}, #{b}" }
p.call(1, 2) # "1, 2"
p.call(1) # "1, " (nil para faltante)
p.call(1, 2, 3) # "1, 2" (extra ignorado)
# Lambda - verificacion estricta de argumentos
l = lambda { |a, b| "#{a}, #{b}" }
l.call(1, 2) # "1, 2"
l.call(1) # ArgumentError!
l.call(1, 2, 3) # ArgumentError!
```
### Lambda_check
```ruby
p = proc { |x| x }
l = lambda { |x| x }
puts p.lambda? # false
puts l.lambda? # true
```
## Lambdas
### Sintaxis Stabby Lambda
```ruby
sumar = ->(a, b) { a + b }
puts sumar.call(2, 3) # 5
cuadrado = ->(n) { n ** 2 }
puts cuadrado.call(5) # 25
```
### Lambda como Argumento de Metodo
```ruby
numeros = [1, 2, 3, 4, 5]
# En lugar de bloque
dobles = numeros.map(&:to_i) # Symbol to proc
dobles = numeros.map { |n| n * 2 }
# Con lambda
numeros.each(&->(n) { puts "Numero: #{n}" })
```
## De Bloques a Procs
### Operador Ampersand
```ruby
def metodo_que_hace_yield
yield if block_given?
end
proc = -> { puts "Hola" }
metodo_que_hace_yield(&proc)
# Symbol to proc
nombres = ["alice", "bob"]
nombres_mayusculas = nombres.map(&:upcase)
```
## Closures
```ruby
# Los bloques capturan variables locales
def multiplicador(factor)
->(numero) { numero * factor }
end
doble = multiplicador(2)
triple = multiplicador(3)
puts doble.call(5) # 10
puts triple.call(5) # 15
```
## Resumen de Argumentos de Metodos
| Sintaxis | Descripcion |
|---------|-------------|
| `def foo(a)` | Argumento posicional |
| `def foo(a=1)` | Argumento con valor por defecto |
| `def foo(*a)` | Posicional variable |
| `def foo(a:)` | Argumento de palabra clave |
| `def foo(a: 1)` | Palabra clave con valor por defecto |
| `def foo(**a)` | Splat de palabra clave |
| `def foo(&a)` | Bloque como proc |
## Resumen
- Metodos: `def...end`, retorno implicito/explicito
- Bloques: `do...end` o `{ }`, pasados a metodos
- `yield`: ejecuta el bloque
- Procs: `Proc.new`, `proc`, almacenados como objetos
- Lambdas: `lambda { }` o `->()`, verificacion estricta de argumentos
- Operador `&`: convierte bloque a proc o proc a bloque
- Closures: los bloques capturan el ambito circundante
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →