Namespaces on clojure, and compilation.

O uso de namespaces em clojure pode ser bem simples, mas pode ser bem complicado. Vou focar no simples :)

O namespace de clojure está próximo da declaração pacote/classe no java, assim o padrão é o mesmo para nomenclatura (apesar de poder variar), dessa forma o arquivo clojure em src/twitter/search.clj teria normalmente o ns (ns = namespace) twitter.search.

A declaração básica de um namespace é a através do macro “ns”:

(ns twitter.search)  

Com os arquivos definidos com seus devidos namespace, e o classpath (cp) do java configurado certo (apontando para o src/, por exemplo, você pode chamar outros arquivos clojure pelo seu ns:

(ns twitter.main  	(:require twitter.search)  )  

Agora você teria o ns twitter.search disponível em seu main, mas a forma mais prática é a seguir:

(ns twitter.main  	(:require [twitter.search :as search)  )  

Assim o conteúdo do ns twitter.search está no simbolo alias search, dessa forma para chamar a função "search-timeline" do twitter.search você faz:

(search/search-timeline "clojure")  

Outra forma útil no ns é o "use", que traz os simbolos do outro ns para o ns atual, assim:

(ns twitter.main (:use twitter.search))  (search-timeline "clojure")  

Agora podemos também compilar nossa aplicação clojure, tendo por exemplo a seguinte estrutura de arquivos:

/app  /app/src  /app/src/twitter  /app/src/twitter/main.clj  /app/src/twitter/search.clj  /app/classes  /app/libs  

Considerando que seus .jars do clojure estão no libs, conforme este texto, você deve então passar a lancar o clojure com o seguinte comando (veja o novo classpath):

java -cp ./:./src/:./classes/:libs/clojure.jar:libs/clojure-contrib.jar clojure.main $1  

Agora podemos definir um método main no nosso twitter/main.clj :

(ns twitter.main    (:require [twitter.search :as search]))  (defn -main [word]    (let [tweets (search/search word)]      (println (reduce (fn [t0 t1]                          (str t0 "\n"                           (get t1 "at") " @" (get t1 "from") " : " (get t1 "text")                          )) "Search result" tweets ))  ))  

E o twitter/search.clj:

(ns twitter.search    (:use clojure.contrib.json.read)    (:require [clojure.contrib.http.agent :as http ])    )

  (defn search [word]    (let [json (http/string                     (http/http-agent                         (str "http://search.twitter.com/search.json?q=" word)) )]      (map         (fn [tweet] {"from" (get tweet "from_user")                     "text" (get tweet "text")                     "at" (get tweet "created_at")})        (get (read-json json) "results"))    )  )  

Como pode-se ver usamos tanto o use como o require, assim como as funções mega-hyper-uteis de map e reduce para excercício.

Mais então para compilar o projeto, lance o REPL executando apenas o “./clj” e mande compilar com:

(compile 'twitter.main)  

Agora suas classes estão na pasta classes, você pode executar a aplicação rodando:

$ java -cp ./libs:./classes:./libs/clojure.jar:./libs/clojure-contrib.jar twitter.main clojure  

Assim vai rodar o -main recebendo o “clojure” como argumento. Crie agora o script de start-up e pronto.

Bonus: uma versão em um script de 30 linhas formatadas de uma busca no twitter com clojure. Basta executar o .clj.

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>