我在Clojure编程中偶然发现了一段代码,它有很多buggy。我是Clojure的新手,不知道代码中的bug在哪里。
(ns ring-tutorial.core
(:require [compojure.handler :as ch]
[compojure.core :refer [GET PUT POST defroutes]]
[compojure.route :as cr]
[ring.util.response :as response]))
(def ^:private counter (atom 0))
(def ^:private mappings (ref {}))
(defn url-for
[id]
(@mappings id))
(defn shorten!
"Stores the given URL under a new unique identifier and returns it as a string."
([url]
(let [id (swap! counter inc)
id (Long/toString id 36)] ;;convert to base 36 string
(or (shorten! url id)
(recur url))))
([url id] ;;url is provided with an id.
(dosync
(when-not (@mappings id)
(alter mappings assoc id url)
id))))
(defn retain
[& [url id :as args]]
(if-let [id (apply shorten! args)]
{:status 201
:headers {"Location" id}
:body (list "URL " url " assigned the short identifier " id " \n")}
{:status 409 :body (format "Short URL %s is already taken \n " id)}))
(defn redirect
[id]
(if-let [url (url-for id)]
(ring.util.response/redirect url) ;;Appropriately redirect the URL based on ethe ID.
{:status 404 :body (str "No such short URL: \n" id)})) ;;Return a 404 if no URL for the particular ID found.
(defroutes app*
(GET "/" request "Hello World!")
(PUT "/:id" [id url] (retain url id))
(POST "/" [url ] (retain url))
(GET "/:id" [id] (redirect id))
(GET "/list/" [] (interpose "\n" (keys @mappings)))
(cr/not-found "Its a 404!\n"))
(def app (ch/api #'app*))当我运行$ CURL POST 'localhost:8080/? URL =http://www.yahoo.com/‘时,当我重新运行命令I get’时,我的get -X已经被赋予了标识符1,但是它应该会标记一个错误,说明yahoo.com已经具有标识符1。
这是一个错误,我可以看到它是在缩短!函数,但一直没有能够纠正它。
谢谢!
发布于 2013-07-09 22:16:19
在shorten!函数中,您需要获取一个URL,并查看是否已经为其分配了ID。相反,您每次都会生成一个新的ID,并在地图中查找它,以查看是否为其分配了URL,但这种情况永远不会发生。
为了解决这个问题,您需要维护第二个映射,即从长URL到短ID的映射。在dosync块中,您将首先在这个新映射中查找URL,如果没有找到URL,则生成一个ID,并将URL对添加到两个映射中。
https://stackoverflow.com/questions/17549967
复制相似问题