Cuando conocí las Gemas Rubí, parecían bastante mágicas. Ejecutando bundle install
podía adquirir de alguna manera estas gemas mágicas que harían que mi código hiciera todo tipo de cosas que parecían estar muy por encima de mis habilidades de estudiante de la primera semana de Flatiron. Al igual que las «cajas de objetos» de Mario Kart, las gemas parecen otorgar superpoderes al usuario.
Tengo la intención de utilizar mi blog para profundizar en los conceptos de programación que despiertan mi curiosidad y que no entiendo del todo. Para mi primera entrada en el blog, voy a desmentir la naturaleza mística y mágica de las gemas de Ruby.
¿Qué es una gema de Ruby?
No, las gemas de Ruby no son mágicas. Son simplemente bibliotecas de código abierto que contienen código Ruby y están empaquetadas con un poco de información extra . El uso de una gema permite a un programador utilizar el código dentro de la gema en su propio programa, sin insertar explícitamente ese código.
Las gemas se pueden utilizar para todo tipo de propósitos, y puedes explorar diferentes gemas en https://rubygems.org/. Para tener una mejor idea de lo que las gemas pueden hacer, aquí hay un par de gemas populares y su funcionalidad:
- Bundler – Proporciona un entorno consistente para los proyectos de Ruby mediante el seguimiento y la instalación de las gemas exactas y las versiones que se necesitan. Es la gema número 1 descargada de todos los tiempos, pero más adelante hablaremos de Bundler.
- RSpec – Un marco de trabajo de pruebas que soporta el Desarrollo Dirigido por el Comportamiento (Behavior Driven Development) para Ruby.
- Devise – Devise trabaja con autenticación. Para cualquier sitio web que necesite el inicio de sesión de los usuarios, Devise gestiona el inicio de sesión, el registro, el restablecimiento de la contraseña, etc.
- JSON – Proporciona una API para analizar JSON a partir de texto.
- Nokogiri – Proporciona analizadores HTML, XML, SAX y Reader con soporte para selectores XPath y CSS.
- Rails – ¡Rails es una joya! Rails proporciona el marco de trabajo fullstack que permite transformar Ruby en aplicaciones web.
Instalación de gemas
¡Hoy en día, usar gemas es fácil! Instalar gemas localmente es tan sencillo como un solo comando: gem install
. El comando install busca el código, lo descarga en tu ordenador e instala la gema y las dependencias necesarias. Finalmente, construirá la documentación para las gemas instaladas.
Mientras que algunas gemas, como Bundler, sólo requieren la instalación de 1 gema, otras gemas tienen dependencias que requieren la instalación de múltiples gemas:
Para ver todas las gemas instaladas localmente, utilice el comando, gem list
.
Usar gemas
Ahora, lo más importante, ¿cómo podemos usar nuestras gemas instaladas? Bueno, depende del tipo de gema. Algunas gemas, como Rails, son programas Ruby independientes que puedes ejecutar desde el comando.
Otras son relativamente inútiles por sí mismas, pero increíblemente útiles cuando se usan dentro de un proyecto. Para utilizar una gema desde dentro de su código, es necesario requerirla primero en la parte superior del archivo – require 'gem_name'
. Por ejemplo, Pry se ha convertido rápidamente en una de mis gemas favoritas cuando se trabaja en proyectos. Mi código i̶s̶n̶’̶t̶ ̶a̶l̶w̶a̶y̶s̶ casi nunca es correcto cuando lo escribo por primera vez, y Pry hace que la depuración sea mucho más eficiente y un poco menos dolorosa. Esta semana pasada, aprendimos sobre las APIs y necesitamos Pry y un par de gemas más para completar el proyecto.
Aunque las gemas son muy sencillas si sólo las necesitas en tu ordenador, se vuelven algo más complicadas si quieres distribuir o publicar tu proyecto. Cualquier otra persona que ejecute tu proyecto necesitará tener todas las gemas necesarias y las versiones correctas instaladas en su ordenador. Afortunadamente, tenemos RubyGems y Bundler que agilizan el proceso.
RubyGems es el marco que simplifica el compartir gemas
Parte de la magia de las gemas es que todos podemos usarlas, y RubyGems es el gestor de paquetes que lo hace posible. Proporciona un formato estándar para distribuir gemas de Ruby, gestiona la instalación de gemas y un servidor para distribuirlas. RubyGems no fue lanzado al público hasta el 14 de marzo de 2004 (¡el día de Pi! π) Aunque RubyGems ha existido desde Ruby 1.8, no fue parte de la distribución estándar de Ruby hasta Ruby 1.9. Así que para los novatos en Ruby, como yo, RubyGems se instala automáticamente en tu ordenador cuando instalas Ruby.
¿Cómo vivían los rubyistas sin RubyGems?
La vida era mucho más difícil. Si quieres la historia completa, te recomiendo que veas la presentación de André Arko «¿Cómo funciona Bundler, de todos modos?» de la RailsConf 2015. Aquí está mi versión resumida:
La carga de código comenzó con require
, y el uso de require
es esencialmente el mismo que la inserción del código en su archivo. En su forma más simple, es un método que extrae código del archivo de argumentos.
def require(filename)
eval File.name(filename)
end
Require permite a los usuarios cargar cualquier código local, buscando el archivo en el $LOAD_PATH del usuario. $LOAD_PATH es una variable global y una matriz de rutas absolutas. Siempre y cuando el directorio del código se encuentre en algún lugar dentro de $LOAD_PATH, require
será capaz de encontrarlo.
Aunque require
es genial para el código local, ¿qué pasa si quieres obtener código de otra persona? Era un proceso tedioso – tendrías que encontrar el código, descargarlo, guardarlo en algún lugar de tu ordenador y añadirlo al $LOAD_PATH.
Como resultado, setup.rb evolucionó para facilitar el proceso. Setup.rb (que sigue existiendo hoy en día) es un instalador genérico para scripts y bibliotecas de Ruby. Era una mejora importante sobre require
porque copiaba todos los archivos de Ruby en un directorio que ya estaba en el $LOAD_PATH. Los desarrolladores son inherentemente perezosos, y setup.rb nos ahorró un par de pasos. Sin embargo, setup.rb tenía su propio conjunto de problemas. No había seguimiento de la versión y no había forma de desinstalar un programa. La única forma definitiva de saber qué versión tenías era anotar el número de versión en la instalación. Como puedes imaginar, el uso de las bibliotecas era un pequeño desastre.
¡En 2004, RubyGems vino al rescate! ¡Ahora el código de otras personas, o gemas, podía ser instalado o desinstalado con un solo comando! Fue revolucionario. RubyGems tenía otro truco bajo la manga – podía manejar diferentes versiones de software, y cada versión se mantenía en su propia carpeta separada.
Bundler resuelve las dependencias de las gemas
Tan increíble como parecía RubyGems, tenía un defecto inherente. Si querías compartir un proyecto, ¿cómo te asegurabas de que un nuevo usuario tuviera todas las gemas necesarias? Con la configuración actual de RubyGems, si un desarrollador ejecutaba gem install foo
y empezaba a usar una nueva gema en la aplicación, había que decirle a otros desarrolladores del proyecto que ejecutaran gem install foo
. Ciertas gemas sólo podían funcionar con ciertas versiones de otras gemas, y se hacía cada vez más difícil coordinar las dependencias de gemas y versiones.
¡Así que llegamos a Bundler! Bundler existe para resolver el problema de la dependencia de versiones de gemas mediante el seguimiento y la instalación de las gemas y versiones exactas que se necesitan. Bundler trabaja a través de un «gemfile» de Ruby que le dice a Bundler qué gemas buscar y dónde buscarlas. https://rubygems.org es la fuente por defecto, pero si existen gemas en un servidor privado, esa fuente puede ser sobrescrita para esas gemas específicas.
Después de instalar las gemas necesarias (si tu ordenador no las tiene ya), Bundler escribirá todas las gemas y versiones que instaló en otro archivo, Gemfile.lock. Este archivo de bloqueo permite instalar exactamente las mismas versiones en cada máquina que ejecute la aplicación.
Usar Bundler es sencillo. Primero, es necesario instalarlo, y como Bundler es una gema en sí misma, podemos hacerlo con: gem install bundler
. Con Bundler instalado, puedes usar cualquier gema en tu propio proyecto en 2 pasos:
- Agrega la gema a un Gemfile en la raíz de tu proyecto
- Ejecuta
bundle install
en tu terminal
Para más detalles de Bundler, consulta http://bundler.io/.