Novedades en Rails 4.2: config_for

Hasta ahora un patrón bastante común en aplicaciones Rails que necesitan de un fichero de configuración era encontrarse en el config/application.rb algo parecido a esto:

require "ostruct"
config_file = File.join("config/myapp.yml")
config = YAML.load(File.read(config_file))[Rails.env]
AppConfig = OpenStruct.new(config)

De esa manera podíamos usar el objeto AppConfig en toda la aplicación y así llevar a nuestros controladores o modelos algunas variables de configuración que debían cambiar dependiendo del entorno (host y puerto para Redis, número de segundos de delay que indicar a un worker Sidekiq en el perform_in, app id y secret de una API externa, etc).

Suele pasar en la comunidad Rails que conforme un patrón de este tipo empieza a ser muy usado acabe siendo adaptado e incorporado al propio framework. En este caso, en la versión 4.2 nos llega en la forma de config_for.

Supongamos que tenemos un fichero llamado config/redis.yml con el siguiente contenido:

development:
  host: localhost
  port: 6379
test:
  host: localhost
  port: 6379
production:
  host: my-production-redis-server
  port: 6379

Ahora podemos hacer la siguiente llamada en la aplicación:

> Rails.application.config_for(:redis)
=> {"host"=>"localhost", "port"=>6379}

El valor del hash en este ejemplo dependería del entorno en el que nos encontrásemos.

Podéis encontrar más información acerca de config_for en el propio pull request en el que se incorporó a Rails.

The coding zone

De un tiempo a esta parte se lleva popularizando entre las bitácoras de desarrolladores el compartir lo que cada uno define como su “coding zone”, su entorno de trabajo ideal para tener sesiones de programación lo más productivas posibles.

En mi caso, mi entorno ideal se compone de cuatro pilares fundamentales.

Buena música

No lo puedo evitar, me encanta la música. Y a la hora de trabajar me ayuda a concentrarme en las tareas que tengo que realizar.

En mi caso a la hora de programar no tengo predilección en especial por géneros musicales. Lo que sí que suelo optar es mucho por la escucha de directos (El Alchemy de Dire Straits es uno de mis favoritos).

No suelo optar por escuchar playlists autogeneradas por parte de iTunes o Spotify. En ambas plataformas tengo listas de varios géneros compuestas poquito a poco a lo largo de estos años que me evitan tener que perder el foco al encontrarme con una canción que no me guste.

Tanto estos últimos años de trabajo en remoto, como anteriormente cuando trabajaba en oficinas con más gente, unos buenos cascos siempre me han acompañado. Hay momentos en los que necesitas ese aislamiento.

Sin interrupciones

Procuro concentrar las reuniones que tenga que mantener o a primera hora o a última. Así minimizo en gran medida el cambio de contexto que supone volver a la resolución de la tarea en la que me encuentre enfrascado en ese momento.

También procuro que sean lo más breves posibles. Una reunión de media hora por Skype en realidad es un tiempo de al menos una hora de programación perdida. Los 15 minutos previos a la reunión en los que estás ya pensando en la reunión más que en la tarea, la reunión propiamente dicha, y otros 15 minutos para volver a concentrarte al 100% en la tarea que tenías entre manos.

Sobre todo en épocas donde nos marcamos deadlines ajustados, las notificaciones las reduzco al mínimo. Móviles en modo silencio o modo avión, correo cerrado, y otras aplicaciones solo con las notificaciones más importantes activadas (por ejemplo, en HipChat solo las menciones directas).

Organización

Tres componentes definen este área:

  • Todas las historias que componen el proyecto en el que trabajo están gestionadas a través de Pivotal Tracker. Una pestaña fija en el navegador.
  • Mantengo en Evernote una libreta donde voy almacenando artículos técnicos que voy necesitando (bendito Web Clipper).
  • Things recopila todas las tareas, tanto del trabajo como asuntos personales, que debo atacar. Todas las acciones que supongan más que una respuesta rápida de menos de unos pocos minutos queda anotada por aquí, y dos veces al día el Inbox es revisado.

Motivación por lo que haces

Esto es básico. Es imposible ser productivo en tu trabajo si no sientes cada mañana cuando te pones delante de la pantalla que te espera un día interesante, cargado de retos.

¿De qué se compone tu “coding zone”?

Clases curiosas en Rails

Por muchos años que lleves utilizando Rails, siempre te encontrarás navegando por la documentación con clases de lo más útiles y que probablemente estés usando de forma indirecta sin conocerlo.

Intentaré a lo largo de una serie de entradas como ésta ir contando cosas sobre algunas de las más importantes “en la sombra”.

ActiveSupport::StringInquirer

Introducida en la versión 2.2, y dando un uso curioso a method_missing, esta clase es la que está detrás de la “magia” de que:

Rails.env == "production"

también se pueda escribir como:

Rails.env.production?

En una clase real podríamos hacer algo como:

class Video
  def initialize(title)
    @title = title
  end

  def title
    ActiveSupport::StringInquirer.new(@title)
  end
end

v = Video.new("awesome")
v.title.radical? # => false
v.title.awesome? # => true
ActiveSupport::MessageVerifier

Esta clase nos acompaña desde Rails 2.3. Al igual que la clase anterior, es raro que la hayas utilizado de forma directa, pero seguro que más de una vez en tu código has escrito algo como

cookies.permanent.signed[:remember_me] = [current_user.id, current_user.salt]

La implementación de cookies.signed se basa en el uso de MessageVerifier, una clase especializada en generar mensajes firmados con una clave (en el caso de las cookies, ActionController::Base.cookie_verifier_secret). Para MessageVerifier un mensaje puede ser tanto una cadena de texto como cualquier cosa susceptible de ser serializada.

>> @verifier = ActiveSupport::MessageVerifier.new("nuestra-clave-secreta")
=> #<ActiveSupport::MessageVerifier:0x007fe10cb32438 @secret="nuestra-clave-secreta", @digest="SHA1", @serializer=Marshal>
>> @verifier.generate(["Hola", "Mundo"])
=> "BAhbB0kiCUhvbGEGOgZFVEkiCk11bmRvBjsAVA==--f2c2e657ec1501c984d8c44154b398a3a2ac9cbc"
>> mensaje_cifrado = @verifier.generate(["Hola", "Mundo"])
=> "BAhbB0kiCUhvbGEGOgZFVEkiCk11bmRvBjsAVA==--f2c2e657ec1501c984d8c44154b398a3a2ac9cbc"
>> @verifier.verify(mensaje_cifrado)
=> ["Hola", "Mundo"]

Dentro de la serialización por defecto se utiliza Marshall, pero si por ejemplo preferimos utilizar YAML podríamos hacer algo como:

@verifier.serializer = YAML

Y hasta aquí por hoy. ¿Qué otras clases curiosas te has encontrado utilizando Rails en tu día a día?