Использование протокола Clojurescript?

Делаем первый шаг при использовании протоколов в ClojureScript. Ниже приводится определение / реализация протокола:

(defprotocol IDataTable
  (-pages [this])
  (-cnt! [this cnt])
  (-paginate [this])
 )

(deftype DataTable [id url info]
 IDataTable
 (-cnt! [_ cnt] (swap! info (fn [v] (assoc v :cnt cnt))) )
 (-pages [_]
   (inc (.round js/Math (/ (:cnt @info) (:length @info))))
 )

(-paginate [_]
  (let [arr (take 5 (drop (- (:page @info) 1) (range 1 (pages))))]
   (c/paging id (flatten ["Prev" arr "Next"]) )
  ))
 )

Я запутался в том, как вызывать функции, определенные в протоколе.

Ниже приведен код для создания экземпляра:

(def table-id "some-table")
(def paging (atom {:page 1 :length 10 :cnt 0  }))
(def data-table (DataTable. table-id "/list/data" paging))

Приведенный выше код работает и может получить доступ к свойствам, используя следующую форму:

(js/alert (.-id data-table))

Проблема, с которой я сталкиваюсь, заключается в том, как вызывать функции, определенные в протоколе. Следующие формы приводят к ошибке (время выполнения).

 (-cnt! data-table 10) ;; Error: -cnt! is not a method
 (.-cnt! data-table 10) ;; Error

Просматривая сгенерированный код Javascript, он получил длинные имена для функций.

Спасибо

РЕДАКТИРОВАТЬ: думаю, я нашел ответ. Похоже, мне нужны вспомогательные функции в пространстве имен.

(defn cnt! [t cnt]
   (when (satisfies? IDataTable t)
     (-cnt! t cnt))
 )

С помощью функции, определенной выше, я могу получить доступ к функциям. Интересно, это правильный подход?

РЕДАКТИРОВАТЬ 2: Хорошо, с дальнейшим анализом сгенерированного кода javascript понял, что не нужны вспомогательные функции, как вышеописанное редактирование, вызовы функции должны иметь префикс с пространством имен

 (:require [table :as tbl])

(def table-id "some-table")
(def paging (atom {:page 1 :length 10 :cnt 0  }))
(def data-table (DataTable. table-id "/list/data" paging))

 (tbl/-cnt! data-table 10) ;; Works!!!

1 ответ

Похоже, вы ответили на свой вопрос, но на случай, если кто-нибудь окажется здесь...

Методы протокола автоматически переводятся в пространство имен, в котором они объявлены, это означает, что если вы хотите вызывать те функции, которые вы вызываете, как если бы они были обычными функциями в пространстве имен.

Другие вопросы по тегам