Ruby, conocido por su elegancia y expresividad, esconde algunas funcionalidades que, aunque no siempre son las primeras que aprendemos, pueden hacer nuestra vida como desarrolladores mucho más sencilla, profesional y eficiente. ¡Prepárate para descubrir gemas ocultas en el mundo Ruby! Así mismo visita su sitio web oficial para saberlo todo de Ruby. También visita nuestro blog para saber más de tecnología.

1. El Poder del tap
El método tap
es una joya para encadenar operaciones y depurar sin interrumpir el flujo. Ejecuta un bloque de código en un objeto y luego devuelve el objeto mismo.
Ruby
def process_user(user)
user.tap { |u| puts "Usuario antes de cambios: #{u.inspect}" }
.update(name: "Nuevo Nombre")
.tap { |u| puts "Usuario después de la actualización del nombre: #{u.inspect}" }
.activate!
.tap { |u| puts "Usuario activado: #{u.inspect}" }
end
class User
attr_accessor :name, :active
def initialize(name)
@name = name
@active = false
end
def update(attributes)
attributes.each { |key, value| send("#{key}=", value) if respond_to?("#{key}=") }
self
end
def activate!
@active = true
self
end
end
user = User.new("Usuario Viejo")
process_user(user)
# Salida:
# Usuario antes de cambios: #<User:0x000000010xxxxxxx @name="Usuario Viejo", @active=false>
# Usuario después de la actualización del nombre: #<User:0x000000010xxxxxxx @name="Nuevo Nombre", @active=false>
# Usuario activado: #<User:0x000000010xxxxxxx @name="Nuevo Nombre", @active=true>
2. El Conciso Operador de «Safe Navigation» (&.
)
Evita los molestos NoMethodError
cuando trabajas con objetos que podrían ser nil
. Si el objeto antes de &.
es nil
, la expresión entera se evalúa a nil
en lugar de lanzar un error.
Ruby
user = User.new("Alice")
puts user&.address&.city # Si user o address es nil, esto imprimirá nil sin error
user_sin_direccion = User.new("Bob")
puts user_sin_direccion&.address&.city # Imprime nil
3. Bloques Como Argumentos Implícitos (&block
)
Puedes pasar bloques (closures) a métodos sin definirlos explícitamente como un parámetro normal. Dentro del método, el bloque se convierte en un objeto Proc
accesible a través de la variable block
.
Ruby
def with_greeting(&block)
puts "¡Saludos!"
block.call("Mundo") if block
puts "¡Adiós!"
end
with_greeting { |place| puts "Hola, #{place}!" }
# Salida:
# ¡Saludos!
# Hola, Mundo!
# ¡Adiós!
def calculate(a, b, operation)
operation.call(a, b)
end
add = ->(x, y) { x + y }
subtract = ->(x, y) { x - y }
puts calculate(5, 3, add) # 8
puts calculate(10, 2, subtract) # 8
4. Hashes con Sintaxis de Símbolos Concisa
Ruby ofrece una sintaxis más limpia para crear hashes donde las claves son símbolos.
Ruby
persona = { nombre: "Carlos", edad: 35, ciudad: "Toluca" }
puts persona[:nombre] # Carlos
Esto es equivalente a:
persona = {:nombre => "Carlos", :edad => 35, :ciudad => "Toluca"}
5. Rangos para Iteración y Condiciones
Los rangos en Ruby son increíblemente versátiles para iterar y verificar si un valor está dentro de un intervalo.
Ruby
# Iteración sobre un rango inclusivo
(1..5).each { |i| puts i } # Imprime 1, 2, 3, 4, 5
# Iteración sobre un rango exclusivo
(1...5).each { |i| puts i } # Imprime 1, 2, 3, 4
# Verificar si un valor está dentro de un rango
edad = 22
if (18..65).include?(edad)
puts "Es adulto en edad laboral."
end
6. El Método yield_self
(anteriormente then
)
Similar a tap
, pero en lugar de devolver el objeto original, yield_self
devuelve el resultado del bloque. Esto es útil para encadenar transformaciones.
Ruby
resultado = "texto".upcase.yield_self { |t| t.reverse }.yield_self { |r| "Resultado final: #{r}" }
puts resultado # Resultado final: TXET
numero = [1, 2, 3].yield_self { |arr| arr.map { |x| x * 2 } }.yield_self { |dobles| dobles.sum }
puts numero # 12
7. Métodos Dinámicos con send
El método send
te permite llamar a métodos en un objeto pasando el nombre del método como un símbolo o una cadena. Esto es poderoso para metaprogramación.
Ruby
class Calculadora
def sumar(a, b)
a + b
end
def restar(a, b)
a - b
end
end
calc = Calculadora.new
operacion = :sumar
resultado = calc.send(operacion, 5, 3)
puts resultado # 8
operacion = "restar"
resultado = calc.send(operacion, 10, 4)
puts resultado # 6
8. El Método itself
Un método simple pero a veces útil que simplemente devuelve el objeto sobre el que se llama. Puede hacer que ciertas construcciones con bloques sean más legibles.
Ruby
nombres = ["ana", "BETO", "carla"]
nombres_en_minusculas = nombres.map(&:downcase) # Uso común de &:symbol
nombres_filtrados = [1, "dos", 3, nil, 5].compact.map(&:itself)
puts nombres_filtrados.inspect # [1, "dos", 3, 5]
9. El Método slice
en Arrays y Strings
slice
ofrece formas flexibles de extraer porciones de arrays y strings utilizando rangos o índices.
Ruby
arreglo = [0, 1, 2, 3, 4, 5]
puts arreglo.slice(2..4).inspect # [2, 3, 4]
puts arreglo.slice(1, 3).inspect # [1, 2, 3]
puts arreglo.slice(-2..-1).inspect # [4, 5]
cadena = "Hola Mundo"
puts cadena.slice(5..9) # Mundo
puts cadena.slice(0, 4) # Hola
10. El Método dig
para Acceder a Hashes y Arrays Anidados
Evita múltiples comprobaciones de existencia al acceder a estructuras de datos anidadas.
Ruby
configuracion = {
api: {
version: "v1",
endpoints: {
users: "/users",
products: "/products"
}
}
}
puts configuracion.dig(:api, :endpoints, :users) # /users
puts configuracion.dig(:api, :database, :host) # nil (no existe)
Te dejo un video donde explico algunos Patrones de Diseño Web y donde se menciona algunas caracteristicas de Ruby y los patrones que usa.
Conclusión
Ruby está lleno de estas pequeñas pero poderosas características que pueden hacer tu código más conciso, legible y eficiente. ¡Anímate a explorar la documentación y a experimentar con estas gemas ocultas para llevar tus habilidades en Ruby al siguiente nivel!