Como encontro protocolos implementados no objeto Clojure?

9

Existe uma maneira documentada de descobrir quais protocolos são implementados por um objeto Clojure? O contrário (mostrar para quais classes um determinado protocolo é estendido) é fácil: (protocolo extensores).

    
por Maurits Rijk 10.01.2011 в 22:35
fonte

2 respostas

5

Acabei com a seguinte implementação:

(defn protocol? [maybe-p]
  (boolean (:on-interface maybe-p)))

(defn all-protocols []
  (filter #(protocol? @(val %)) (ns-publics *ns*)))

(defn implemented-protocols [sym]
  (filter #(satisfies? @(val %) sym) (all-protocols)))

Primeiro, ele procura todos os símbolos no namespace atual (você pode estender isso para todos os namespaces), sejam eles definições de protocolo ou net (todos os protocolos). Em seguida, ele procura por um determinado símbolo se satisfizer um desses protocolos.

O protocolo? função usa a chave: na interface que não é documentada afaik, então esta função não é portátil.

    
por Maurits Rijk 13.01.2011 / 20:49
fonte
0

Eu não posso realmente tentar isso no momento, mas você pode querer tentar o método de classe Java: getGenericInterfaces . Isso deve fornecer uma lista de interfaces. Provavelmente, existem outras maneiras de obter essas informações usando métodos semelhantes, mas eu não procurei.

Se você também olhar o código-fonte, verá como os protocolos estão configurados (você pode acessar a fonte clicando nos links da API clojure). No Clojure 1.3 existe uma função 'privada' que se parece com isso:

(defn- protocol?
  [maybe-p]
  (boolean (:on-interface maybe-p)))

Esta função é usada pela função extend do Clojure para verificar se você realmente forneceu um Protocolo. Se você fizer sua própria função assim, poderá filtrar os resultados de getGenericInterfaces . Como esse é um detalhe interno, pode estar sujeito a alterações.

    
por hutch 11.01.2011 / 13:22
fonte