В Clojure: ошибка выполнения вызова Java с let внутри функции, но не в REPL

У меня есть следующий код:

(defn post
  [title content timestamp]
    (let [[innholdet tajm]
       [(str "<html>
              <head>
              <title>" title " :: " blog_title "</title></head>
              <body><h1>" title "</h1>
              <br/>" content "<br/><i>posted " (Date. timestamp) "</i>
              <br/><a href=\"" (str blog_url) "\">[main]</a> | 
              <a href=\"" (str blog_url) "/" timestamp ".html\">[permalink]</a>
              </body></html>") (str timestamp".html")]]
                 (spit tajm innholdet)
   )
 )

У меня есть еще одна функция, которая передает заголовок, содержимое и временную метку UNIX функции «post» выше. blog_title и blog_url определяются в начале кода. Я отсортировал HTML для эстетики, в «реальном коде» это не так. я тоже делаю

(import 'java.util.Date)
(use 'clojure.string)

Если я пытаюсь выполнить код, я получаю сообщение об ошибке

java.lang.IllegalArgumentException 

Если я удаляю (Date. timestamp), код выполняется отлично, но мне нужна эта (Date.) функция.

Теперь, если в REPL я делаю

(import 'java.util.Date)

Затем определите переменную с отметкой времени

(def timestamp 1278854531000) ;; Just for pushing a var into (Date.) than just the number

А затем я просто копирую (let) в REPL и настраиваю vars в исходном коде, чтобы они просто представляли разные имена функций вместо значений (поскольку это REPL и vars, функции и значения, которые есть в исходном коде). не существует), чтобы было так:

(let [[innholdet tajm] 
  [(str "<html>
         <head>
         <title>" (str "title") " :: " (str "blog_title") "</title>
         </head>
         <body><h1>" (str "title") "</h1><br/>" (str "content") "<br/>
         <i>posted " (Date. timestamp) "</i><br/>
         <a href=\"" (str "blog_url") "\">[main]</a> | 
         <a href=\"" (str "blog_url") "/" (str "1278854531000") ".html\">[permalink]</a></body></html>") 
         (str "1278854531000.html")]] 
           (println innholdet tajm))

Теперь REPL дает мне:

<html>
<head>
<title>title :: blog_title</title>
</head>
<body>
<h1>title</h1><br/>content<br/>
<i>posted Sun Jul 11 15:22:11 CEST 2010</i><br/>
<a href="blog_url">[main]</a> | 
<a href="blog_url/1278854531000.html">[permalink]</a>
</body></html> 
1278854531000.html
nil

Опять же все сдвинуто, чтобы читалось удобнее, в REPL все выходит одной большой строкой.

Проблема здесь в том, что я могу выполнить код в REPL и получить значение (Date. timestamp), и все работает, но когда я выполняю его внутри функции в своей программе, я получаю вышеупомянутую ошибку. Был бы признателен, если бы кто-нибудь сказал мне, что мне здесь не хватает.


person bleakgadfly    schedule 12.07.2010    source источник
comment
Пробовали закидывать на длинное? (Date. (long timestamp))   -  person Jonas    schedule 12.07.2010
comment
@Jonas Это привело к: Исключение в потоке main java.lang.ClassCastException: java.lang.String не может быть приведено к java.lang.Number и вызвано: java.lang.ClassCastException: java.lang.String не может быть приведено к java .lang.Number на clojure.lang.RT.longCast(RT.java:961)   -  person bleakgadfly    schedule 12.07.2010
comment
@bleakgadfly: Тогда ваш аргумент — это строка, а не число. Вам нужно разобрать строку на число, например. используя длинный/парселонг   -  person j-g-faustus    schedule 13.07.2010
comment
Я попытался использовать Long и получил результат, который я вставил выше, однако, если бы было необходимо использовать (long), не пришлось бы мне использовать его и в REPL? Поскольку он отлично работает без (длинного) в REPL, я не вижу, как это повлияет на полный код.   -  person bleakgadfly    schedule 13.07.2010
comment
Мой опыт показывает, что функция, определенная выше, работает, если передано число, достаточно большое, чтобы не поместиться в int (например, то, которое вы поместили в timestamp Var), но не тогда, когда число действительно помещается в int (поскольку Date не имеет конструктор, принимающий один int). Возможно, вы захотите использовать Long/valueOf (это будет работать с ints, longs и Strings).   -  person Michał Marczyk    schedule 13.07.2010
comment
Похоже, Long/valueOf сделал свое дело :) Спасибо!   -  person bleakgadfly    schedule 13.07.2010


Ответы (1)


Необходимо лишь небольшое изменение:

(defn post
  [title content timestamp]
    (let [[innholdet tajm]
       [(str "<html>
              <head>
              <title>" title " :: " blog_title "</title></head>
              <body><h1>" title "</h1>
              <br/>" content "<br/><i>posted " (Date. **(Long/parseLong timestamp)**) "</i>
              <br/><a href=\"" (str blog_url) "\">[main]</a> | 
              <a href=\"" (str blog_url) "/" timestamp ".html\">[permalink]</a>
              </body></html>") (str timestamp".html")]]
                 (spit tajm innholdet)
   )
 )

Тем не менее, я бы порекомендовал вам найти способ передать отметку времени как long вместо строки.

person Jieren    schedule 13.07.2010