No me voy a extender mucho en los detalles, porque a quien le interese el tema, va a saber más o menos de que hablo, y al que no, ni siquiera lo va a leer. Si querés ir directamente al problema (y a la solución), podés saltar la próxima sección (el versito no fue intencional).
Con que estaba laburando
Sinatra 1.3.2 |
Sinatra is a DSL for quickly creating web applications in Ruby with minimal effort.
dice la documentación de Sinatra. Y es cierto. Usándolo para un par de cosas sencillas, pueden salir cosas muy fácil y rápido. Por otro lado:
Padrino is a ruby framework built upon the Sinatra web library. Sinatra is a DSL for creating simple web applications in Ruby. Padrino was created to make it fun and easy to code more advanced web applications while still adhering to the spirit that makes Sinatra great!dice la documentación de Padrino. Pero más importante, dicen que Padrino tiene Sinatra Core, y que por lo tanto...:
Many people love the simplicity and expressiveness of Sinatra [...].
[...] Our goal with Padrino is to stay true to the core principles of Sinatra including a focus on simplicity and modularity.
Starting from this assumption, we have developed a different approach to a web development framework. We expand on Sinatra through the addition of standard libraries including helpers, components, and other functionality that are needed in a framework suitable for arbitrarily complex web applications.¿Y qué es lo importante de todo esto? Se preguntarán. Que dicen que usa Sinatra Core y que expande Sinatra, es decir, que agarra Sinatra y le agrega cosas o lo mejora, pero no aclaran que también lo rompe un poco.
Que parezca un accidente, supongo. Padrino 0.10.3. |
El problema
Supongamos que tenemos una ruta a una página. La misma tiene algunos parámetros que llamamos
param
, param_opt
y param_opt2
(por ejemplo, si queremos listar posts de un blog, podemos hacer una ruta del estilo /:year
, /:year/:month
, /:year/:month/:day
donde el mes y el día son opcionales, porque con dar sólo el año ya se puede obtener un resultado, y el mes y el día son para acotar los resultados). Como sus nombres declarativos (?) lo sugieren, el primer parámetro es obligatorio y los otros 2 son opcionales.Óptimamente, uno no querría tener que atajar las rutas
hostname.com/:param
hostname.com/:param/:param_opt
hostname.com/:param/:param_opt/:param_opt2
por diversas razones de comodidad y buenas prácticas. Hasta ahora lo único (y bastante) molesto es la repetición de los prefijos, pero supongan (y me pasó) que quieren agregar otro parámetro opcional, pero antes de param. Hay que agregar otros 3 casos para atajar dichas rutas. Y eso no está bueno, más aun si queremos mantenernos con filosofía DRY.Como resuelve Sinatra
Realmente es sencillo. Luego de cada parámetro o caracter opcional, se puede agregar un "?" y eso determina que el parámetro (que puede ser un símbolo como lo describí antes) o caracter anterior, es opcional. Veamos un ejemplo. En:
hostname.com/:param/?:param_opt?
la segunda “/“ y el símbolo
:param_opt
son opcionales. En:hostname.com/:param/?:param_opt?/?:param_opt2?
la segunda y tercer “/“ son opcionales, al igual que los símbolos
:param_opt
y :param_opt2
.
Exactamente como queríamos. Sencillo, ¿no?
Seguro hago esto así en Sinatra, me queda re compacto y lindo, me paso a Padrino y anda, ¿no?
No.
Como resuelve Padrino
No tengo ni idea. Bueno, en realidad si. Como Rails. Un gran conocedor del mundo Ruby y compañero de trabajo (Demian) me lo hizo notar (y le estoy muy agradecido), luego de ver la cantidad incontable de horas que estuve buscando como hacer parámetros opcionales, sin éxito alguno.
No se si a nadie en toda la internet le pasó esto o que, pero no hay nada al respecto. Google te manda a resultados de Stack Overflow, relacionados con Sinatra, entre otras cosas, pero nadie dice que Padrino reemplaza, aparentemente, el router de Sinatra por el de Rails.
Demian sabía que en una aplicación de Rails que hizo había necesitado parámetros de URL opcionales, entonces como no había nada que perder, se fijó como se hacía, y lo probó así. Y funcionó.
La solución es poner parámetros opcionales estilo Rails 3, con paréntesis (sección 3.1 Bound Parameters).
Entonces teniendo:
Conclusión
No se ustedes, pero para mi, cuando alguien basa un producto en otra cosa, la idea no es romper el producto original. O al menos, avisar y documentar bien en caso de haber alguna excepción insalvable.
Todavía no considero tener mucha experiencia en el área, y cabe la posibilidad de que el que se está equivocando al usarlo sea yo, pero para eso están ustedes y sus comentarios, para aclararme el panorama, o que nos juntemos a tomar mate e insultar a los desarrolladores.
No se si a nadie en toda la internet le pasó esto o que, pero no hay nada al respecto. Google te manda a resultados de Stack Overflow, relacionados con Sinatra, entre otras cosas, pero nadie dice que Padrino reemplaza, aparentemente, el router de Sinatra por el de Rails.
Demian sabía que en una aplicación de Rails que hizo había necesitado parámetros de URL opcionales, entonces como no había nada que perder, se fijó como se hacía, y lo probó así. Y funcionó.
La solución es poner parámetros opcionales estilo Rails 3, con paréntesis (sección 3.1 Bound Parameters).
Entonces teniendo:
hostname.com/:param
hostname.com/:param/:param_opt
hostname.com/:param/:param_opt/:param_opt2
se soluciona aplicando los paréntesis correspondientes, quedando:hostname.com/:param(/:param_opt(/:param_opt2))
De esta forma, /:param_opt2
es opcional dentro de /:param_opt
, y a su vez, esta composición es opcional en la dirección entera. En este caso /:param_opt2
no puede aparecer si antes no hubo un /:param_opt
. Si lo que queremos es tener varios parámetros independientes entre sí, en lugar de anidarlos o componerlos como hice ahí, simplemente se pone paréntesis individual a cada parámetro, quedando:hostname.com/:param(/:param_opt)(/:param_opt2)
Conclusión
No se ustedes, pero para mi, cuando alguien basa un producto en otra cosa, la idea no es romper el producto original. O al menos, avisar y documentar bien en caso de haber alguna excepción insalvable.
Todavía no considero tener mucha experiencia en el área, y cabe la posibilidad de que el que se está equivocando al usarlo sea yo, pero para eso están ustedes y sus comentarios, para aclararme el panorama, o que nos juntemos a tomar mate e insultar a los desarrolladores.
No comments:
Post a Comment