Crystal: Lenguaje de programación inspirado en Ruby
Publicado el 13 de marzo de 2019Crystal es un lenguaje de programación de propósito general orientado a objetos. Su sintaxis está inspirada en Ruby pero no busca ser compatible. Surgió del amor a la eficiencia para escribir código de Ruby, y el amor a la eficiencia para ejecutar código C. Busca ser lo mejor de ambos mundos.
Entre las diferencias fundamentales con Ruby se encuentran:
- Es un lenguaje compilado, el código es convertido a código de máquina nativo a través de LLVM. Ruby, por otro lado, es un lenguaje interpretado.
- Tiene un sistema de tipado estático, por lo que la comprobación de tipos se realiza durante la compilación. Esto agrega una capa más de seguridad al código, evitando errors de tipos. Ruby es dinámicamente tipado, por lo que los tipos se revisan en ejecución. Sin embargo, el compilador de Crystal cuenta con un sistema de inferencia de tipos, por lo que no es necesario declarar los tipos de todos los valores y ejecuciones ya que el compilador los puede detectar. De esta manera, el código se mantiene limpio, y esto es parte de la filosofía del lenguaje.
El siguiente código nos muestra la inferencia de tipos en acción:
puts typeof("Fernando") #=> String puts typeof(12) #=> Int32 puts typeof(42.0) #=> Float64 |
También podemos definir el tipo con anotaciones:
@nombre : String @edad : Int32 |
Todo es un objeto: Al igual que en Ruby, en Crystal todo es un objeto (tiene un tipo, responde a algunos métodos).
Recién va por la versión 0.27.2, así que está creciendo y cambiando rápidamente todavía. De todas formas hay algunos valientes que se han animado a usarlo en producción. El proyecto cuenta con un Roadmap que define las cosas que quieren tener en el lenguaje, así como preguntas frecuentes y una excelente documentación.
Otras cosas interesantes de Crystal sobre las que me gustaría escribir más adelante: union types (tipos de datos especiales que pueden poseer varias representaciones), Macros (sistema para meta programación), Modelo de concurrencia e integración con librerías C (tiene una sintaxis dedicada para llamar a bibliotecas nativas de forma sencilla).
Instalar Crystal
Crystal puede ser instalado en Debian, Ubuntu, RedHat, CentOS, Arch Linux, Gentoo, Alpine, FreeBSD, y demás sistemas, desde un tar.gz o compilado desde el código fuente. Si usan el gestor de versiones asdf, hay un plugin para eso. Podemos ver las distintas instrucciones de instalación en la documentación.
El comando crystal
Una vez instalado, deberíamos tener el comando crystal
disponible en nuestra terminal. Los archivos de código fuente Crystal tienen la extensión .cr
. Para ejecutar un archivo de código fuente Crystal, escribimos:
$ crystal run archivo.cr
El comando `run` compila el código a un binario ejecutable en una ubicación temporal y lo ejecuta. Con el comando crystal build
, podemos crear un binario ejecutable:
También existe crystal eval
para pasarle código Crystal a crystal run
desde la línea de comando o a través de un pipe por la entrada estándar. La lista completa de opciones está en la documentación usando el compilador.
Creando proyectos Crystal
El comando crystal
también incluye el parámetro init
, que inicializa un directorio con un proyecto. El primer parámetro de init es el tipo de proyecto. Las dos opciones son lib
, una biblioteca reutilizable y app
, una aplicación sin el objetivo de ser usada como dependencia:
$ crystal init app prueba
create prueba/.gitignore
create prueba/.editorconfig
create prueba/LICENSE
create prueba/README.md
create prueba/.travis.yml
create prueba/shard.yml
create prueba/src/prueba.cr
create prueba/spec/spec_helper.cr
create prueba/spec/prueba_spec.cr
Initialised empty Git repository in /home/fernando/workspace/crystal/prueba/.git/
Shards: Manejo de dependencias
Shards es a Crystal lo que las gemas son a Ruby. Las aplicaciones y bibliotecas Crystal cuentan con un archivo shard.yml que declara las dependencias del proyecto. Shards se distribuye con Crystal, así que lo tenemos disponible en nuestra terminal. Con shard init
, creamos un archivo shard.yml de ejemplo, seguido de shard install
para instalar las dependencias y especificarlas en un archivo shard.lock
.
Por ejemplo en el proyecto recién creado, agrego las siguientes líneas al archivo shard.yml
:
dependencies: cossack: github: crystal-community/cossack version: ~> 0.1
Cossack es un cliente HTTP bastante simple para Crystal. Se instala al ejecutar shards install
y ya lo puedo usar en el código fuente. Dentro del archivo src/prueba.cr
del mismo proyecto escribo:
require "cossack" module Prueba VERSION = "0.1.0" def self.hola response = Cossack.get("https://picandocodigo.net/api") puts response.body end end Prueba.hola |
Y podemos ejecutarlo con crystal run para ver los resultados:
Testeando Código Crystal
Crystal viene equipado con una biblioteca de testing en el módulo Spec. Incluye un DSL (lenguaje de dominio específico) inspirado en RSpec, por lo que resulta súper familiar para programadores Ruby. Cuando inicié mi proyecto más arriba,ya se creó un directorio /spec
con un archivo de ejemplo. Modificando un poco el archivo prueba.cr
para que retorne el valor de lo que obtiene Cossack en vez de imprimirlo en pantalla con puts, podemos escribir un test bastante sencillo:
describe Prueba do it "calls Picando Código's API" do Prueba.hola.should eq "¡Chau!" end end |
Y si corremos los tests, tenemos una falla! (TDDeando, por supuesto):
$ crystal spec
F
Failures:
1) Prueba calls Picando Código's API
Failure/Error: Prueba.hola.should eq "¡Chau!"
Expected: "¡Chau!"
got: "¡Hola!"
# spec/prueba_spec.cr:5
Finished in 744.67 milliseconds
1 examples, 1 failures, 0 errors, 0 pending
Failed examples:
crystal spec spec/prueba_spec.cr:4 # Prueba calls Picando Código's API
Cambiando la expectativa del test a “¡Hola!” hacemos que pase:
describe Prueba do it "calls Picando Código's API" do Prueba.hola.should eq "¡Hola!" end end |
.
Finished in 861.99 milliseconds
1 examples, 0 failures, 0 errors, 0 pending
Como ven, es bastante sencillo empezar a usar Crystal. Espero con este post lograr despertar el interés por el lenguaje, y con suerte tener algún intercambio al respecto. Los comentarios están abiertos si quieren dejar su opinión, ¿conocían Crystal? ¿Le ven futuro?
Por mi parte voy a seguir investigando el lenguaje e intentar escribir algunos proyectitos, así como analizar las herramientas ya disponibles, e iré compartiéndolo por acá.
Más información sobre Crystal:
No hay comentarios en este post
Feed de comentariosDejar un comentario
<pre lang="L"> código </pre>
Siendo L un lenguaje compatible GeSHI. Más info.