RubyIntermedio23 oct 2025
¡El Constante que No Era Tan Constante!
snippet.ruby
DEFAULT_RATE = 1.05
module LoanCalculator
def calculate_interest(principal)
principal * DEFAULT_RATE
end
end
class MortgageLoan
DEFAULT_RATE = 1.03
include LoanCalculator
end
class CarLoan
DEFAULT_RATE = 1.08
include LoanCalculator
end
mortgage_loan = MortgageLoan.new
car_loan = CarLoan.new
puts "Interés de hipoteca (esperado 1.03): #{mortgage_loan.calculate_interest(100)}"
puts "Interés de coche (esperado 1.08): #{car_loan.calculate_interest(100)}"¿Qué crees que imprime?
✅ Salida Esperada
Interés de hipoteca (esperado 1.03): 103.0
Interés de coche (esperado 1.08): 108.0⚠️ Salida Real
Interés de hipoteca (esperado 1.03): 105.0
Interés de coche (esperado 1.08): 105.0¿Por qué pasa esto?
¡Prepárate para un giro inesperado! 🤯 Aquí vemos cómo las **constantes en Ruby** pueden ser un poco... ¡testarudas! Cuando definimos `calculate_interest` dentro de `LoanCalculator`, el método echa un vistazo a `DEFAULT_RATE` en ese preciso momento. Como `LoanCalculator` no tiene su propia `DEFAULT_RATE`, Ruby sube al árbol genealógico y encuentra la `DEFAULT_RATE = 1.05` global. ¡Es como si el método tomara una instantánea de la constante en su nacimiento! 📸
Luego, cuando `MortgageLoan` y `CarLoan` **incluyen** `LoanCalculator` y definen sus propias `DEFAULT_RATE` (1.03 y 1.08 respectivamente), esperaríamos que el método `calculate_interest` usara *esas* nuevas constantes. ¡Pero no! El método ya "decidió" qué `DEFAULT_RATE` usar cuando fue definido. Es un caso claro de **scope léxico** vs. **scope de ejecución**. El método se adhiere a la constante que vio al nacer, ignorando olímpicamente las nuevas definiciones de las clases que lo incluyen. ¡Así que ambos préstamos terminan con la misma tasa global! 🤷♂️
Conceptos relacionados
constant-lookupscopingmodules