Variables: nombrar datos para trabajar con ellos
Una variable es una etiqueta que apunta a un valor. En Ruby no declaras tipos: el valor “sabe” qué es (número, texto, arreglo, etc.).
Asignación básica
Asignas con =:
nombre = "Ana"edad = 28activo = trueRuby permite reasignar sin problema:
edad = 29Asignación múltiple (muy útil con colecciones)
Puedes asignar varias variables en una sola línea:
nombre, edad = "Ana", 28También puedes “desempaquetar” un Array:
- Escuche el audio con la pantalla apagada.
- Obtenga un certificado al finalizar.
- ¡Más de 5000 cursos para que explores!
Descargar la aplicación
datos = ["Ana", 28, "Madrid"]nombre, edad, ciudad = datosSi faltan valores, Ruby asigna nil a lo que no exista:
a, b, c = [1, 2]# a = 1, b = 2, c = nilSi sobran valores, se ignoran (a menos que uses una variable “resto”):
primero, *resto = [10, 20, 30, 40]# primero = 10, resto = [20, 30, 40]Constantes: valores que no deberían cambiar
Una constante empieza con mayúscula. Ruby permite reasignarla, pero te avisará con una advertencia; la idea es que no cambie.
IVA = 0.21MONEDA = "EUR"Úsalas para valores de configuración o reglas de negocio estables.
Alcance (scope) básico: dónde “vive” una variable
El alcance define desde dónde puedes acceder a una variable. En este nivel, quédate con estas reglas prácticas:
- Las variables locales (como
precio) existen dentro del bloque o método donde se crean. - Los bloques (por ejemplo, dentro de
each) pueden ver variables externas y también crear variables internas.
total = 0[10, 20, 30].each do |precio| total += precioend# total sigue existiendo aquíLa variable del bloque (precio) solo tiene sentido dentro del bloque.
nil: ausencia de dato y por qué importa
nil representa “no hay valor”. Aparece cuando algo no existe o no se encontró.
usuario = nilEjemplos típicos:
- Acceder a una clave inexistente en un Hash: devuelve
nil. - Buscar un elemento que no está: puede devolver
nilsegún el método.
Para evitar errores, comprueba antes de usar un valor que podría ser nil:
email = datos[:email]if email puts email.downcaseelse puts "Falta email"endTambién es común usar un valor por defecto:
email = datos[:email] || "sin-email"Array: colecciones ordenadas
Un Array es una lista ordenada de elementos, indexada desde 0.
Creación
numeros = [1, 2, 3]nombres = ["Ana", "Luis"]vacio = []Acceso y actualización
nombres[0] # "Ana"nombres[1] = "Lucía"Si accedes a un índice fuera de rango, obtienes nil:
nombres[10] # nilAñadir elementos: push y <<
numeros.push(4)numeros << 5Recorrer: each
nombres.each do |n| puts nendTransformar: map
map crea un nuevo Array con el resultado de aplicar una transformación a cada elemento.
precios = [10, 20, 30]con_iva = precios.map { |p| p * 1.21 }# [12.1, 24.2, 36.3]Filtrar: select
select devuelve solo los elementos que cumplen una condición.
precios = [10, 20, 30, 5]caros = precios.select { |p| p >= 20 }# [20, 30]Hash: colecciones por clave-valor
Un Hash guarda pares clave => valor. Es ideal para modelar datos con “campos” (como un registro).
Creación
Con símbolos como claves (muy habitual):
persona = { nombre: "Ana", edad: 28, ciudad: "Madrid" }También puedes usar la sintaxis “hash rocket”:
persona = { :nombre => "Ana", :edad => 28 }Acceso y actualización
persona[:nombre] # "Ana"persona[:edad] = 29persona[:email] = "ana@ejemplo.com"Si la clave no existe, devuelve nil:
persona[:telefono] # nilRecorrer: each
persona.each do |clave, valor| puts "#{clave}: #{valor}"endObtener claves y valores: keys y values
persona.keys # [:nombre, :edad, :ciudad, :email]persona.values # ["Ana", 29, "Madrid", "ana@ejemplo.com"]Hash con valores por defecto (útil para conteos)
Cuando vas a acumular cantidades, un valor por defecto evita nil:
conteo = Hash.new(0)conteo[:manzana] += 1conteo[:manzana] += 1conteo[:pera] += 1# {:manzana=>2, :pera=>1}Prácticas guiadas (paso a paso)
1) Transformar una lista (Array + map)
Objetivo: convertir una lista de precios en centavos y aplicar un descuento.
- Paso 1: define el Array.
- Paso 2: transforma con
map. - Paso 3: revisa el resultado.
precios = [9.99, 15.50, 3.25]en_centavos = precios.map { |p| (p * 100).to_i }con_descuento = precios.map { |p| (p * 0.9).round(2) }# en_centavos => [999, 1550, 325]# con_descuento => [8.99, 13.95, 2.93]2) Filtrar elementos (Array + select)
Objetivo: quedarte con productos disponibles (stock > 0).
stocks = [ { nombre: "Camiseta", stock: 10 }, { nombre: "Gorra", stock: 0 }, { nombre: "Pantalón", stock: 3 }]disponibles = stocks.select { |p| p[:stock] > 0 }# disponibles contiene Camiseta y Pantalón3) Agrupar información en hashes (conteo por categoría)
Objetivo: contar cuántos productos hay por categoría.
- Paso 1: prepara una lista de items con categoría.
- Paso 2: crea un Hash con valor por defecto 0.
- Paso 3: recorre y acumula.
items = [ { nombre: "Manzana", categoria: :fruta }, { nombre: "Pera", categoria: :fruta }, { nombre: "Zanahoria", categoria: :verdura }]conteo_por_categoria = Hash.new(0)items.each do |item| categoria = item[:categoria] conteo_por_categoria[categoria] += 1end# {:fruta=>2, :verdura=>1}4) Caso cotidiano: modelar un carrito de compras
Vas a representar un carrito con productos y cantidades. Hay varias formas; una práctica y flexible es usar un Hash donde la clave sea el identificador del producto y el valor sea la cantidad.
Estructura propuesta
carrito = { "SKU-123" => 2, "SKU-999" => 1 }Guía paso a paso
- Paso 1: crea el carrito vacío con valor por defecto 0 para poder sumar sin comprobar
nil. - Paso 2: agrega productos incrementando cantidades.
- Paso 3: actualiza (sumar o restar) y elimina si llega a 0.
- Paso 4: recorre el carrito para mostrar el resumen.
carrito = Hash.new(0)# Paso 2: agregarcarrito["SKU-123"] += 1carrito["SKU-123"] += 1carrito["SKU-999"] += 1# Paso 3: quitar una unidadcarrito["SKU-123"] -= 1# si queda en 0, lo eliminamosif carrito["SKU-123"] <= 0 carrito.delete("SKU-123")end# Paso 4: recorrercarrito.each do |sku, cantidad| puts "#{sku} x #{cantidad}"endEnriquecer el carrito con datos de productos (Array + Hash)
Normalmente tienes un “catálogo” con información de cada producto. Puedes guardarlo en un Hash para acceder rápido por SKU.
catalogo = { "SKU-123" => { nombre: "Camiseta", precio: 12.0 }, "SKU-999" => { nombre: "Gorra", precio: 8.5 }}carrito = { "SKU-123" => 2, "SKU-999" => 1 }total = 0.0carrito.each do |sku, cantidad| producto = catalogo[sku] # puede ser nil si el SKU no existe if producto.nil? puts "Producto desconocido: #{sku}" next end subtotal = producto[:precio] * cantidad total += subtotal puts "#{producto[:nombre]} (#{sku}) x #{cantidad} = #{subtotal}"endputs "TOTAL = #{total}"Observa cómo nil aparece si el SKU no está en el catálogo: manejar esa ausencia evita errores y hace tu código más robusto.
Tabla rápida de métodos habituales
| Tipo | Método | Qué hace | Ejemplo |
|---|---|---|---|
| Array | push / << | Añade al final | a << 3 |
| Array | each | Recorre elementos | a.each { |x| ... } |
| Array | map | Transforma y devuelve nuevo Array | a.map { |x| x*2 } |
| Array | select | Filtra por condición | a.select { |x| x > 0 } |
| Hash | each | Recorre clave y valor | h.each { |k,v| ... } |
| Hash | keys | Devuelve claves | h.keys |
| Hash | values | Devuelve valores | h.values |