2013-06-23 6 views
5

Dla bota IRC piszę, chcę nadal próbować otworzyć gniazdo, nawet jeśli istnieje UnkownHostException. Moja pierwsza myśl była czymś takim.Jak mogę powrócić z bloku catch Clojure w bardziej funkcjonalny sposób?

(defn open-socket [{:keys [host port] :as connection}] 
    (try (java.net.Socket. host port) 
    (catch java.net.UnknownHostException _ (recur connection)))) 

Ale to nie działa, ponieważ nie można powtórzyć z bloku catch. Więc zamiast tego ustaliłem coś takiego:

(let [socket (promise) 
     _ (while (not (realized? socket)) 
      (try (deliver socket (java.net.Socket. host port)) 
       (catch java.net.UnknownHostException _))) 
     socket @socket] 
    ... 

To działa, ale jest okropnie konieczne. Czy istnieje bardziej funkcjonalny sposób, w jaki mogę to robić, czego nie widzę?

Odpowiedz

12

Wystarczy dodać or:

(defn open-socket [{:keys [host port] :as connection}] 
    (or (try (java.net.Socket. host port) 
      (catch java.net.UnknownHostException _ nil)) 
     (recur connection))) 
+0

Clever! Dzięki! – mybuddymichael

0

Jedna z możliwości może być podobna do tej?

(let [make-socket #(try (java.net.Socket. host port) 
        (catch java.new.UnknownHostException _)) 
     socket-attempts (repeatedly make-socket) 
     socket (first (drop-while nil? socket-attempts))] 
    socket) 
Powiązane problemy