2017-09-28 1 views
1

Je travaille donc sur une fonction de flux qui résumera certaines métriques pour plusieurs événements. Pour ce faire, utiliser la fonction project et il ressemble à quelque chose comme ceci:Arguments de variable pour la fonction de projet Riemann

(project [(func (:service event) (nth service-list 0))  
      (func (:service event) (nth service-list 1)) 
      (func (:service event) (nth service-list 2))] 
     (..)) 

service-list est un argument de la fonction environnante, qui contiennent un vecteur de services qui doivent être ajoutés ensemble. func est une fonction qui prend deux arguments et renvoie un true/false L'utilisation de l'extrait ci-dessus fonctionne bien, mais j'aimerais pouvoir le simplifier afin qu'un vecteur plus grand ou plus petit que 3 éléments puisse fonctionner.

Jusqu'à présent, j'ai ceci:

(project (mapv (fn[service] (
        `func (:service event) ~service) 
        ) service-list))) 
      (..) 

que je pense que renvoie un vecteur de fonctions qui sont évaluées. Je suis allé avec cette approche une fois que j'ai réalisé que project est une macro. Aucune idée si je fais la bonne chose ...

Répondre

1

Le problème que vous rencontrez est que vous ne pouvez pas assembler dynamiquement seulement les arguments d'un appel de macro. Par conséquent, vous devez assembler dynamiquement l'appel de macro entier.

Vous pouvez créer un formulaire clojure et appeler le eval. Prenez ce qui suit.

(let [args (mapv #(list 'func (:service 'event) %) service-list) 
      form (list 'project args (...))] 
     (eval form)) 

Ou, vous pouvez également utiliser la fonction riemann.streams/project* utiliser fonctions sous-jacentes au lieu de expressions.