Hablemos sobre los módulos en Ruby ¿que son? ¿en que difieren de las clases? ¿por qué son útiles?
Los módulos en Ruby son similares a las clases, almacenan múltiples métodos. Sin embargo tu no puedes crear una nueva instancia de un módulo, como sí lo puedes hacer con las clases, los módulos no poseen el método new
.
Podemos pensar en los módulos como mix-ins, estos permiten inyectar pedazos de código en una clase. Los mix-ins exportan una funcionalidad deseada a una clase sin crear una relación “es un/a”. En Ruby podemos agregar la cantidad de módulos que deseemos a las clases, a diferencia de la herencia que sólo puede hacerse una sola vez por clase.
El libro Well-Grounded Rubyist tiene un maravilloso ejemplo de cuando es necesario usar un módulo.
Cuando estás diseñando un programa e identificas un comportamiento o un conjunto de comportamientos que pueden exhibidos por mas de un objeto, has encontrado un buen candidato para ser extraido a un módulo.
Para crear un módulo se utiliza casi la misma sintaxis que usamos para crear clases, la única diferencia es que usamos el keyword module
en lugar de class
.
moduleStacklikedefstack
@items ||= []
enddefpush(obj)
items.push(obj)
enddefpop
items.pop
endend
Para poder hacer uso del módulo que acabamos de crear en una clase podemos hacer uso de uno de estos keywords: include
, prepend
y extend
.
classStackinclude Stacklike
end
Eso es todo lo que es necesario para poder inyectar todos los métodos que nos provee Stacklike
en nuestra clase Stack
. Con el siguiente ejemplo podemos ver su funcionamiento:
stack = Stack.new
stack.push('First item')
stack.push('Second item')
stack.push('Third item')
puts 'Estos objetos están actualmente en la pila:'
puts stack.items
last_item = stack.pop
puts 'Se removió de la pila:'
puts last_item
puts 'Estos objetos están actualmente en la pila:'
puts stack.items
💡 En Ruby por lo general se usan adjetivos para nombrar los módulos. Esto se hace con el fin de reforzar la noción de que los módulos definen un comportamiento.
Tener ambos aspectos disponibles crea un montón de opciones a escoger, pero esto tiene un lado complejo y es que también debes ser muy cuidadoso sobre los detalles que ambas aproximaciones introducen.
La sobre-modularización existe. Evita dividir todo en módulos porque piensas que algo que escribiste para una entidad será útil en otras entidades. Ahora tienes las herramientas necesarias para que consideres como balancear tus decisiones.
Espero les guste y recuerden dejar su like al post ❤️
Este post es traducido de un post de mi autoría en Dev.to: My Journey into Ruby: Modules