как передать карту в функцию с аргументами ключевого слова

У меня есть такая функция:

pdfkit-clj.core/gen-pdf
 [html & {:keys [path tmp asset-path stylesheets margin orientation page-size], :or {path (:path defaults), tmp (:tmp defaults), asset-path (:asset-path defaults), margin {}, orientation (:orientation defaults), page-size (:page-size defaults)}}]

Теперь я пытаюсь передать ему карту с ключевыми словами, которые не работают.

(let [gen_pdf_args {:tmp tmp_dir
                     :margin {:top 0 :right 0 :bottom 0 :left 0}}] 
        (gen-pdf html-black gen_pdf_args)
)

Эта проблема аналогична превращению списка в аргументы.


person m33lky    schedule 16.05.2017    source источник
comment
Первый связанный вопрос имеет три разных подхода к решению проблемы; Я согласен с главным ответом, что лучший подход состоит в том, чтобы держаться подальше от этой ситуации, не записывая функции для использования развернутых аргументов ключевого слова, но если вы не можете изменить интерфейс функции, я думаю, что второй связанный вопрос имеет лучший ответ о том, как чтобы обойти проблему.   -  person amalloy    schedule 16.05.2017


Ответы (2)


Использование & {:keys [...]} на самом деле не предполагает, что вы вызовете его с картой. Вместо этого вы называете это как (gen-pdf html :tmp tmp_dir :margin {:top 0}).

Если вы действительно хотите использовать свою карту, вы можете применить ее и сгладить, например (apply gen-pdf html-black (-> gen_pdf_args vec flatten)).

person Alejandro C.    schedule 16.05.2017
comment
Я это понимаю. Я создаю аргументы программно или хочу установить аргументы за один раз. - person m33lky; 16.05.2017
comment
Смотрите мою правку. apply должен решить вашу проблему. - person Alejandro C.; 16.05.2017
comment
Да, я должен использовать для этого что-то легкое, вместо того, чтобы полагаться на внешние библиотеки. - person m33lky; 16.05.2017

Похоже, вы хотите что-то похожее на функцию keyvals:

(keyvals m)
 "For any map m, returns the keys & values of m as a vector,
  suitable for reconstructing via (apply hash-map (keyvals m))."

(keyvals {:a 1 :b 2})
;=> [:b 2 :a 1]
(apply hash-map (keyvals {:a 1 :b 2}))
;=> {:b 2, :a 1}

Обратите внимание, что вам все еще нужно использовать apply, как сказал Алехандро. Дополнительную информацию можно найти keyvals здесь.

person Alan Thompson    schedule 16.05.2017
comment
Да, это хорошо; просто имейте в виду, что keyvals не является частью ядра - person Alejandro C.; 16.05.2017
comment
Просто используйте (apply concat xs) или (mapcat seq xs) вместо того, чтобы импортировать целую большую библиотеку для использования (keyvals xs). - person amalloy; 16.05.2017