he el siguiente código para una biblioteca de conversión genérica:Clojure: La generación de funciones de plantilla
(defn using-format [format] {:format format})
(defn- parse-date [str format]
(.parse (java.text.SimpleDateFormat. format) str))
(defn string-to-date
([str]
(string-to-date str (using-format "yyyy-MM-dd")))
([str conversion-params]
(parse-date str (:format (merge (using-format "yyyy-MM-dd") conversion-params)))))
tengo que ser capaz de llamar así:
(string-to-date "2011-02-17")
(string-to-date "2/17/2011" (using-format "M/d/yyyy"))
(string-to-date "2/17/2011" {})
El tercer caso es un tanto problemático: el mapa no contiene necesariamente la clave :format
que es crítica para la función. Es por eso que merge
con valor predeterminado.
Necesito tener una docena de funciones similares para las conversiones entre todos los demás tipos. ¿Hay alguna manera más elegante que no requiera que copie y pegue, use merge
etc. en cada función?
Idealmente, buscando algo como esto (macro?):
(defn string-to-date
(wrap
(fn [str conversion-params]
(parse-date str (:format conversion-params))) ; implementation
{:format "yyyy-MM-dd"})) ; default conversion-params
... que produciría una función sobrecargada (unario y binario), con tener un binario merge
como en el primer ejemplo.
¿Por qué necesitamos este 'let' y' eval' aquí (en comparación con mi propia respuesta)? Es posible sin cambiar 'parse -date' - Puedo usar '(parse-date to-convert (: format conversion-params))' en la función anónima. –
Sí, eso es cierto, "tener que" está mal, "pensé que era más limpio pasar el todo el conjunto de parámetros para las funciones auxiliares como un patrón general, pero eso es una cuestión de gusto "es lo que debería haber dicho. Lo único que le otorga let/eval es la capacidad de pasar de alguna forma que se evalúa a un mapa de parámetros , en lugar del propio mapa de parámetros. Como los macro argumentos no se evalúan, debe evaluarlos usted mismo en el cuerpo de la macro. Esto solo le permite especificar (formato de uso "aaaa-MM-dd") a s el mapa predeterminado en lugar de literal. – mblinn
Una nota rápida sobre por qué pensé que pasar el mapa de param a una función de ayuda es más claro como un patrón general: como puedes desestructurar ese mapa como parte del enlace de funciones, tienes una sintaxis agradable y concisa para obtener los parámetros. Esto sería útil para las funciones de conversión que tienen mapas de parm con varias claves. – mblinn