У меня есть входящие ленивые строки потока из файла, который я читаю с помощью tail-seq (для вклада - сейчас!), И я хочу обработать эти строки одну за другой с несколькими "функциями слушателя"", который принимает действие в зависимости от повторных попаданий (или других вещей) в строках.
Я пробовал следующее:
(defn info-listener [logstr]
(if (re-seq #"INFO" logstr) (println "Got an INFO-statement")))
(defn debug-listener [logstr]
(if (re-seq #"DEBUG" logstr) (println "Got a DEBUG-statement")))
(doseq [line (tail-seq "/var/log/any/java.log")]
(do (info-listener logstr)
(debug-listener logstr)))
, и это работает, как и ожидалось.Тем не менее, в коде очень много дублирования кода и других грехов, и обновление кода скучно.
Один важный шаг, по-видимому, заключается в применении многих функций к одному аргументу, то есть
(listen-line line '(info-listener debug-listener))
и используйте это вместо скучного и подверженного ошибкам оператора do.
Я попробовал следующий, казалось бы, умный подход:
(defn listen-line [logstr listener-collection]
(map #(% logstr) listener-collection))
, но это только делает
(nil) (nil)
, что лень или функции первого класса меня кусают наверняка,но куда мне положить заявку?
Я также открыт для радикально другого подхода к проблеме, но это, кажется, вполне разумный способ начать с.Макросы / мульти методы пока кажутся излишними / неправильными.