1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Clojureでfuzzy-getとsleep関数を作ってみる

1
Posted at

ClojureでsleepするにはJavaのThread/sleepを使えばいいわけですが、(sleep 1 :min) (sleep 2 :minute) (sleep 3 :s)などのように単位をつけてsleepできるものを作ってみます。

単位についてはある程度あいまいに指定が可能なように、前方一致していればマップから値を取得できるfuzzy-get関数も一緒に作ります。

※ついでにfuzzy-getはkeyが文字列かキーワードかシンボルか区別せずに取れるようにもしておきます。
※複数該当する場合は辞書順で早いほうとします。

fuzzy-get.clj
(defn name? [x] (or (string? x) (instance? clojure.lang.Named x)))

(defn fuzzy-get [hmap key]
  (if (or (not (map? hmap)) (contains? hmap key)) (get hmap key)
    (let [f #(if (name? %) (name %) (str %))
          ks (sort-by f (keys hmap))]
      (some #(when (.startsWith ^String (f %) (f key)) (get hmap %)) ks))))
user=> (def v {:abc 1 "aiu" 2})
user=> (fuzzy-get v 'ab)
1
user=> (fuzzy-get v :ai)
2

#脱線しますが、varやnamespaceはNamedではないようですね。

user=> (instance? clojure.lang.Named :a)
true
user=> (instance? clojure.lang.Named 'a)
true
user=> (instance? clojure.lang.Named #'instance?)
false
user=> (instance? clojure.lang.Named (the-ns 'user))
false

これでfuzzy-getができたので、次はsleepです。

sleep.clj
(def time-unit
  (apply hash-map (interleave [:_milliseconds :seconds :minutes :hours :days]
                              (reductions * [1 1000 60 60 24]))))

(defn ^long milliseconds [^double t unit]
  (long (* t (fuzzy-get time-unit unit))))

(defn sleep
  ([^long ms] (Thread/sleep ms))
  ([^double t unit] (sleep (milliseconds t unit))))

これで(sleep 3 :sec) (sleep 0.1 :m)などでsleepできるようになりました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?