Size: a a a

Clojure — русскоговорящее сообщество

2020 May 08

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
:arglists у меня популярное
(defn verify-identity-token
 "https://developer.apple.com/documentation/signinwithapplerestapi/verifying_a_user#3383769"
 {:arglists '([token, public-key, client-id, {:keys [alg, max-age, now, leeway, skip-validation]}])}

 [token, public-key, client-id, opts]

 (jwt/unsign token public-key (-> opts
                                  (assoc :iss identity-token-issuer)
                                  (assoc :aud client-id))))
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Denis Muraviev
Хм погуглю инлайнтестс. Шо то новое. Спасибо
типа такого
(defn match-event-id-pattern?
 "Test if event ID string match to Game Analytics requirements."
 {:test (fn []
          (t/is (match-event-id-pattern? "part1:part2:part3:part4:part5"))
          (t/is (match-event-id-pattern? "part1:part2:part3:part4(.!?_-)"))
          (t/is (match-event-id-pattern? "request:push:open:game-daily-bonus-available"))
          (t/is (not (match-event-id-pattern? "part1:part2:part3:part4:part5:part6"))))}
 [event-id]
 (re-matches event-id-pattern event-id))
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Sergey Trofimov
типа такого
(defn match-event-id-pattern?
 "Test if event ID string match to Game Analytics requirements."
 {:test (fn []
          (t/is (match-event-id-pattern? "part1:part2:part3:part4:part5"))
          (t/is (match-event-id-pattern? "part1:part2:part3:part4(.!?_-)"))
          (t/is (match-event-id-pattern? "request:push:open:game-daily-bonus-available"))
          (t/is (not (match-event-id-pattern? "part1:part2:part3:part4:part5:part6"))))}
 [event-id]
 (re-matches event-id-pattern event-id))
тесты вообще хороший описатель того, что именно делает функция — на примерах
источник

DM

Denis Muraviev in Clojure — русскоговорящее сообщество
Та да
источник

DM

Denis Muraviev in Clojure — русскоговорящее сообщество
Тока их не всегда есть.
источник

DM

Denis Muraviev in Clojure — русскоговорящее сообщество
Спасибо
источник

DM

Denis Muraviev in Clojure — русскоговорящее сообщество
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Denis Muraviev
В смысле описываешь? Коммент? Дистракчеринг?
или вот такое

(defn query-domain-user-ids
 "Call `loginDomainUser` in authproxy microsvc."
 [{:keys [domainUserIdList] :as data}]
 #_(comment "Response example" {:512702462043 ["E_USER_NOT_FOUND"],
                                :454362390911 ["E_OK" "146657137969"]})
 (if (empty? domainUserIdList)
   {}
   (->> (make-blocking-request "queryDomainUserIds" data)
        (keep (fn [[k [_status id]]] (when id
                                       [(name k) id])))
        (into {}))))
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
в кложе столько разных вариантов, при том, что это остаётся кодом, а не тупым непроверяемым комментарием
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Denis Muraviev
В смысле описываешь? Коммент? Дистракчеринг?
ну и конечно примеры использования внутри (comment) прям под функцией
всегда можно в репле дёрнуть, ну и как иллюстрация к использованию
источник

DM

Denis Muraviev in Clojure — русскоговорящее сообщество
Хорошая тема для блога не напишешь?
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
и делаю я это не для других, а в первую очередь для себя, чтобы всегда глянуть можно быть и понять
ну и всякий раз, когда я гляжу на свой код и не понимаю, то стараюсь сделать выводы и придумать защиту 😊
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
Denis Muraviev
Хорошая тема для блога не напишешь?
не знаю
это всё-таки достаточно opinionated 😊
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
да и код мне писать нравится больше, чем тексты для блога 😀
источник

DM

Denis Muraviev in Clojure — русскоговорящее сообщество
Лучше чем ничто
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
потом текст напишешь, половина читателей тебя обосрёт
я понимаю, что другая половина порадуется, но вот осадочек...
источник

DM

Denis Muraviev in Clojure — русскоговорящее сообщество
Лол ну половина наврядли
источник

ST

Sergey Trofimov in Clojure — русскоговорящее сообщество
могу с кем-нибудь хорошо излагающим скооперироваться
в плане генерации идей
источник

MA

Mike Ananev in Clojure — русскоговорящее сообщество
Denis Muraviev
Я сталкиваюсь последнее время с проблемой в клоуже когда смотрю сторонние проекты. Когда например функция принимает Мапу чуток трансформирует и передаёт дальше. Так вот после третей четвертой функции не понять как должна выглядеть мапа. Если нет тестов или спеки
Не смешивай несколько уровней программы в один.
На верхнем уровне представляй свою программу как последовательность функций, которые обрабатывают некий запрос. Например:
(-> init-request
parse-params
validate-params
security-check
transform-request
enrich-data
save-db
make-response)

Это верхнеуровневый флоу твоей программы. Тут важно понимать из названия, что происходит в целом с изначальным запросом. Детали реализации каждой функции не важны. Важно описание изначального запроса в виде спеки.

Теперь спускаемся в детали реализации каждой функции.
Функция делает строго одно бизнесовое действие. Она принимает на вход мапу с запросом и должна выдать некую мапу с ответом (либо трансформированный входной запрос либо новый ответ).
Что хорошо в функциях, так это то, что при реализации деталей тебе вообще не важно, что есть в остальной системе. Ты работаешь над конкретной функцией и все что нужно определеяется входными параметрами этой функции, а также выходом, который ты хочешь получить. Вход и выход ты можешь фиксировать в виде: докстрингов, pre-post условий, тестами, спекой, комменты (все эти инструменты описания логики, входа и выхода можно использовать в любой комбинации).
Поэтому ты четко видешь, что на входе в функе и что на выходе.
Получается, что в репле или отладочном println ты можешь видеть флоу всего процесса, а также входы и выходы из каждой функции. И у тебя не будет проблем, что после 3 функи ты не понимаешь что на входе или выходе.
источник

v

vveare138 in Clojure — русскоговорящее сообщество
Mike Ananev
Не смешивай несколько уровней программы в один.
На верхнем уровне представляй свою программу как последовательность функций, которые обрабатывают некий запрос. Например:
(-> init-request
parse-params
validate-params
security-check
transform-request
enrich-data
save-db
make-response)

Это верхнеуровневый флоу твоей программы. Тут важно понимать из названия, что происходит в целом с изначальным запросом. Детали реализации каждой функции не важны. Важно описание изначального запроса в виде спеки.

Теперь спускаемся в детали реализации каждой функции.
Функция делает строго одно бизнесовое действие. Она принимает на вход мапу с запросом и должна выдать некую мапу с ответом (либо трансформированный входной запрос либо новый ответ).
Что хорошо в функциях, так это то, что при реализации деталей тебе вообще не важно, что есть в остальной системе. Ты работаешь над конкретной функцией и все что нужно определеяется входными параметрами этой функции, а также выходом, который ты хочешь получить. Вход и выход ты можешь фиксировать в виде: докстрингов, pre-post условий, тестами, спекой, комменты (все эти инструменты описания логики, входа и выхода можно использовать в любой комбинации).
Поэтому ты четко видешь, что на входе в функе и что на выходе.
Получается, что в репле или отладочном println ты можешь видеть флоу всего процесса, а также входы и выходы из каждой функции. И у тебя не будет проблем, что после 3 функи ты не понимаешь что на входе или выходе.
а если твоя функа делает io?
источник