Manejo de dependencias en Ruby con Bundler
Bundler es una manejador de dependencias para Ruby. Aunque viene incluido con Rails, Bundler no es exclusivo de Rails, lo puedes usar para manejar las dependencias de cualquier proyecto de Ruby.
La mayoría de los proyectos en los que vas a trabajar van a utilizar una o más librerías. Una librería no es más que código empaquetado que alguien publica y que puedes utilizar en tus proyectos. Todos los lenguajes de programación tienen alguna forma de crear, distribur y usar librerías. En Ruby, a las librerías se les conoce con el nombre de gemas. Cualquier persona puede crear y publicar una gema.
Instalar una gema en tu máquina es muy fácil, solo debes ejectuar el comando gem install
seguido del nombre de la gema. Por ejemplo, para instalar Ruby on Rails puedes ejecutar:
$ gem install rails
Este comando instalaría la versión más reciente de Rails, pero si deseas instalar otra versión lo puedes hacer con la opción -v
. Por ejemplo:
$ gem install rails -v 4.2.7
Bundler
Instalar individualmente cada una de las gemas de las que depende un proyecto puede ser muy engorroso, además de que sería necesario mantener una documentación actualizada con la lista de gemas y la versión de cada una por si cambiamos de máquina o entra un nuevo integrante a nuestro equipo.
El segundo problema es que puedes tener varias versiones de la misma gema instalada. Por defecto Ruby utiliza la última versión de la gema, pero es posible que esa no sea la que tu proyecto necesite.
Veamos cómo Bundler nos ayuda a solucionar estos problemas.
Bundler es una gema, así que el primero paso es instalarlo con el siguiente comando:
$ gem install bundler
Para definir las dependencias de nuestro proyecto creamos un archivo de texto llamado Gemfile
(sin extensión) en el que vamos a listar las gemas de las que depende nuestro proyecto:
source 'https://rubygems.org'
gem 'nokogiri'
gem 'rack', '~>1.1'
gem 'sinatra', '1.4.7'
La primera línea le dice a Bundler la URL del servidor desde donde se deben instalar las gemas. RubyGems es el servicio de Ruby en donde están almacenadas todas gemas públicas.
Las demás líneas definen las gemas de las que depende nuestro proyecto. Si omites la versión -como en el caso de nokogiri arriba- Bundler asume que deseas utilizar la última versión disponible. Existen varias formas de especificar la versión, veamos algunos ejemplos:
gem 'rails', '4.2.7' # la versión 4.2.7 exactamente
gem 'rails', '>=4.2.7' # cualquier versión igual o mayor que 4.2.7
gem 'rails', '>=4.2.7', '<5.0.0' # igual o mayor que 4.2.7, pero menor que 5.0.0
Los siguientes dos son casos especiales pero muy comunes, de hecho es una muy buena práctica defnir las versiones de esta forma:
gem 'rails', '~>4.2.7' # igual o mayor que 4.2.7, pero menor que 4.3.0
gem 'rails', '~>4.2' # igual o mayor que 4.2.0, pero menor que 5.0.0
La mayoría de gemas utilizan el siguiente esquema de versionamiento: dada una version X.Y.Z
, X
se incrementa cuando hay cambios mayores que son incompatibles con versiones anteriores, Y
se incrementa cuando hay nuevas funcionalidades que son compatibles con versiones anteriores, Z
se incrementa cuando se solucionan bugs y sigue siendo compatible con versiones anteriores.
A esto se le conoce como versionamiento semántico.
Cargar gemas de Github directamente
También es posible cargar una gema de su repositorio de Github directamente:
gem 'papertrail', github: 'germanescobar/papertrail'
En este caso se asumiría que quieres cargar el último commit de la rama master
, pero puedes especificar cualquier rama:
gem 'papertrail', github: 'germanescobar/papertrail' branch: 'my-branch'
Esto es muy útil cuando necesitas funcionalidad que aún no está en la última versión de la gema, o cuando necesitas hacer cambios propios a la gema (p.e. para solucionar algún bug).
Instalar las gemas
Una vez que tienes las gemas definidas en el Gemfile
, puedes instalarlas en tu máquina local con el siguiente comando:
$ bundle install
Este comando crea un archivo Gemfile.lock
con las versiones de las gemas que se van a utilizar en el proyecto. Es buena práctica agregar este archivo al sistema de control de versiones. Recuerda volver a ejecutar este comando cada vez que hagas cambios al archivo Gemfile
.
Configurar la aplicación
Nota: Esto solo es necesario cuando no estás utilizando Ruby on Rails.
El último paso es agregar la siguiente línea al punto de entrada de tu aplicación para asegurar que todas las gemas sean encontradas:
require 'bundler/setup'
# requiere las gemas que necesites normalmente
# el resto de tu aplicación ...
Si tu aplicación necesita muchos require
puedes utilizar la siguiente línea para que Bundler lo haga por ti:
require 'bundler/setup'
Bundler.require(:default)
# el resto de tu aplicación ...
Usando grupos
Con Bundler puedes agrupar tus dependencias y de esa forma realizar operaciones sobre un grupo entero. Veamos el siguiente Gemfile
de ejemplo:
# Estas gemas están en el grupo :default
gem 'nokogiri'
gem 'sinatra'
gem 'wirble', :group => :development
group :test do
gem 'faker'
gem 'rspec'
end
group :test, :development do
gem 'capybara'
gem 'rspec-rails'
end
gem 'cucumber', :group => [:cucumber, :test]
Ruby on Rails utiliza la agrupación de dependencias de Bundler para definir diferentes ambientes de la aplicación (desarrollo, producción y pruebas). Puedes hacer lo mismo en otros proyectos que no sean de Rails.
Por ejemplo, para requerir todas las gemas que están en el grupo :default
y :development
puedes hacer lo siguiente:
require 'bundler/setup'
Bundler.require(:default, :development)
# el resto de tu aplicación ...
Conclusión
Bundler es quizá una de las herramientas más importantes del ecosistema de Ruby, y de la programación en general porque inspiró otros sistemas de manejo de dependencias como npm (en Node JS) y pip (en Python).
Espero que este post te haya ayudado a aclarar qué es Bundler y su rol en Ruby on Rails; y que de esta forma puedas aprovechar todo su potencial!

Descarga gratis el e-book
Conoce la mentalidad, los roles y las tecnologías que debes saber para convertirte en desarrollador Web.
Descargar e-book