Úprava kódu malého programu v Clojure do funkcií

jano6

Úprava kódu malého programu v Clojure do funkcií
« kdy: 11. 03. 2022, 13:55:31 »
Zdravím, mám príklad v Clojure, ktorý funguje, ale je potrebné ho nejako upraviť
do funkcií aby bol kosher. Language server ma upozorňuje, že inline definície nie sú
vhodné, tak som dal definície nad main funkciu.

Ale mám to problém nejako dať dokopy do funkcie connect. Potrebujem vrátiť
dáta, ukončiť inbox a store. Poznám x jazykov ale s LISPom má môj mozog zatiaľ
problém.


Kód: [Vybrat]
(ns pop3.core
  (:import (jakarta.mail Session Folder)))

(def user "username")
(def password "passsword")
(def host "pop3.mailtrap.io")
(def port 9950)


;; (defn connect []
;;   (let [props (System/getProperties)
;;         session (Session/getDefaultInstance props)
;;         store (.getStore session "pop3")
;;         inbox (.getFolder store "Inbox")]


;;     (.connect store host port user password)
;;     (.open inbox Folder/READ_ONLY)
;;     (def messages (.getMessages inbox))
;;     (.close inbox true)
;;     (.close store)
;;     messages)


(def props (System/getProperties))

(def session (Session/getDefaultInstance props))
;; (.setDebug session true)
(def store (.getStore session "pop3"))
(.connect store host port user password)
(def inbox (.getFolder store "Inbox"))
(.open inbox Folder/READ_ONLY)
(def messages (.getMessages inbox))


(defn -main []

  (println (count messages))

  (doseq [m messages] (let [subject (.getSubject m) body (slurp (.getInputStream m))]
                        (println subject)
                        (println body)
                        (prn "---------------------------")))

  (.close inbox true)
  (.close store))

Toto sú závislosti:

Kód: [Vybrat]
  :dependencies [[org.clojure/clojure "1.10.3"]
                 [com.sun.activation/jakarta.activation "2.0.1"]
                 [com.sun.mail/jakarta.mail "2.0.1"]]
  :main pop3.core/-main
« Poslední změna: 11. 03. 2022, 14:25:53 od Petr Krčmář »


Re:Úprava kódu malého programu v Clojure do funkcií
« Odpověď #1 kdy: 11. 03. 2022, 21:07:41 »
https://clojure.org/guides/learn/functions

Task              Java                     Clojure    
Instantiation        new Widget("foo")      (Widget. "foo")
Instance method  rnd.nextInt()             (.nextInt rnd)
Instance field       object.field                (.-field object)
Static method      Math.sqrt(25)            (Math/sqrt 25)
Static field           Math.PI                      Math/PI

a je vymalovani, v hlave si to prepises do javy, nasekas to do funkci a vratis do clojure :-)
nic v tom neni, jen zpusob zapisu je "divny"

jano6

Re:Úprava kódu malého programu v Clojure do funkcií
« Odpověď #2 kdy: 11. 03. 2022, 22:31:23 »
https://clojure.org/guides/learn/functions

Task              Java                     Clojure    
Instantiation        new Widget("foo")      (Widget. "foo")
Instance method  rnd.nextInt()             (.nextInt rnd)
Instance field       object.field                (.-field object)
Static method      Math.sqrt(25)            (Math/sqrt 25)
Static field           Math.PI                      Math/PI

a je vymalovani, v hlave si to prepises do javy, nasekas to do funkci a vratis do clojure :-)
nic v tom neni, jen zpusob zapisu je "divny"

Túto časť som viac-menej pochopil. Podarilo sa mi prepísať Groovy kód do Clojure a funguje
to.

Čo sa mi nepodarilo je prepísať tento kód do osobitnej funkcie:

Kód: [Vybrat]
(def props (System/getProperties))

(def session (Session/getDefaultInstance props))
;; (.setDebug session true)
(def store (.getStore session "pop3"))
(.connect store host port user password)
(def inbox (.getFolder store "Inbox"))
(.open inbox Folder/READ_ONLY)
(def messages (.getMessages inbox))

Funkcia by mala sa pripojiť na store, stiahnuť emaily do listu, uzavrieť prostriedky
a vrátiť dáta callerovi. Funkcia by sa mala volať z main funkcie.

Usmolil som niečo takého:

Citace
;; (defn connect []
;;   (let [props (System/getProperties)
;;         session (Session/getDefaultInstance props)
;;         store (.getStore session "pop3")
;;         inbox (.getFolder store "Inbox")]


;;     (.connect store host port user password)
;;     (.open inbox Folder/READ_ONLY)
;;     (def messages (.getMessages inbox))
;;     (.close inbox true)
;;     (.close store)
;;     messages)

Ale nefunguje to. Čiže kód je funkčný, emaily sa stiahnu, ale zatiaľ neviem
kód pekne upratať idiomaticky à la Clojure.
« Poslední změna: 11. 03. 2022, 22:33:00 od jano6 »

Re:Úprava kódu malého programu v Clojure do funkcií
« Odpověď #3 kdy: 11. 03. 2022, 22:57:57 »
Mno je to takove krpate.....
Kód: [Vybrat]
(defn connect []
  (let [session (Session/getDefaultInstance props)
        store (.getStore session "pop3")
        _ (.connect store host port user password)
        inbox (.getFolder store "Inbox")
        _ (.open inbox Folder/READ_ONLY)
        messages (.getMessages inbox)]
    (.close inbox true)
    (.close store)
    messages))


Snad by to i mohlo fungovat a language server by nemusel nadavat... ale stejne bych se kouknul po nejaky clojure knihovne co tu jakartu zabali...

Pracovat s tema side efektama je fakt osklive...

jano6

Re:Úprava kódu malého programu v Clojure do funkcií
« Odpověď #4 kdy: 11. 03. 2022, 23:41:34 »
Mno je to takove krpate.....
Kód: [Vybrat]
(defn connect []
  (let [session (Session/getDefaultInstance props)
        store (.getStore session "pop3")
        _ (.connect store host port user password)
        inbox (.getFolder store "Inbox")
        _ (.open inbox Folder/READ_ONLY)
        messages (.getMessages inbox)]
    (.close inbox true)
    (.close store)
    messages))


Snad by to i mohlo fungovat a language server by nemusel nadavat... ale stejne bych se kouknul po nejaky clojure knihovne co tu jakartu zabali...

Pracovat s tema side efektama je fakt osklive...

Aha, takže sa tam dá discard. Diq. Funguje to čiastočne. Padne to s hláškou Folder is not open.
Zrejme tie dáta bude treba vytiahnuť z kolekcie messages už priamo v tej connect funkcii, nejako asi
cez map a vrátiť. (V main funkcii je store už uzatvorený).

Clojure má postal knižnicu, ale tá je len pre SMTP, POP tam nie je.




Re:Úprava kódu malého programu v Clojure do funkcií
« Odpověď #5 kdy: 12. 03. 2022, 07:42:00 »
Jeste vidim treba https://github.com/MayDaniel/clj-mail
Je to starsiho data... ale treba to porad funguje....

Ale i kdyby ne... muzes tam kouknout do kodu...
Je to wrapper pro javax.mail a ma to ~80 radku...
Tak by se asi dalo inspirovat a upravit to pro jakartu...

Je tam pekne videt jak se da udelat to "samo-zaviratko"... napriklad with-folder

Re:Úprava kódu malého programu v Clojure do funkcií
« Odpověď #6 kdy: 12. 03. 2022, 09:38:24 »
Usmolil som niečo takého:

Citace
;; (defn connect []
;;   (let [props (System/getProperties)
;;         session (Session/getDefaultInstance props)
;;         store (.getStore session "pop3")
;;         inbox (.getFolder store "Inbox")]


;;     (.connect store host port user password)
;;     (.open inbox Folder/READ_ONLY)
;;     (def messages (.getMessages inbox))
;;     (.close inbox true)
;;     (.close store)
;;     messages)


Asi první věcí by bylo nahrazení def messages za další blok let, tedy let [messages (.getMessages inbox)]. Z let-u to messages vrátíš úplně jednoduše.