Clojure механизм побега времени компиляции - PullRequest
1 голос
/ 22 октября 2010

Язык Forth предлагает механизм экранирования "во время компиляции", где код может быть выполнен немедленно, пока компилятор работает (не во время выполнения). Вы можете включить операторы печати, например, для отладки сложного синтаксиса или ошибок типа).

Есть ли у Clojure что-нибудь подобное? Я получаю исключение IllegalArgumentException во время компиляции в одном из моих вызовов функций и хотел бы добавить оператор печати во время компиляции, чтобы определить тип аргумента ((.getClass)).

Спасибо.

ОБНОВЛЕНИЕ : Вот полное defn, которое не удалось компиляции:

(ns my.ns.name
  (:gen-class
   :main true)
  (:use
   [clojure.contrib.str-utils2 :only (join)])
  (:import
   [java.io PrintWriter]
   [java.net URL]
   [java.util.concurrent Executors]
   [java.util.jar Manifest]
   [org.apache.commons.cli CommandLine HelpFormatter Options Option ParseException PosixParser]))

(defn set-version
  "Set the version variable to the build number."
  []
  (def version
    (-> (str "jar:" (.. my.ns.name (getProtectionDomain)
                                   (getCodeSource)
                                   (getLocation))
                    "!/META-INF/MANIFEST.MF")
      (URL.)
      (.openStream)
      (Manifest.)
      (.. getMainAttributes)
      (.getValue "Build-number"))))

Это defn работает:

(defn set-version
  "Set the version variable to the build number."
  []
  (println (str (.getClass my.ns.name)))
  (def version
    (-> (str "jar:" (-> my.ns.name (.getProtectionDomain)
                                   (.getCodeSource)
                                   (.getLocation))
                    "!/META-INF/MANIFEST.MF")
      (URL.)
      (.openStream)
      (Manifest.)
      (.. getMainAttributes)
      (.getValue "Build-number"))))

1 Ответ

2 голосов
/ 22 октября 2010

Печать класса вещей во время компиляции довольно ограничена особыми случаями. В основном вы получите символы и последовательности. Только литералы имеют осмысленный тип во время компиляции. Вы можете выполнить произвольный код во время компиляции через макросы.

(defmacro debug-type
  [x]
  (println (type x))
  x)

Однако, как я уже сказал, это обычно не очень помогает. И нет: в общем, вы не можете обернуть x в eval, например. если x является символом, относящимся к локальному символу.

РЕДАКТИРОВАТЬ: Обновление обновленного вопроса.

(def version
  (-> (str "jar:" (-> *ns* (.getProtectionDomain)
                           (.getCodeSource)
                           (.getLocation))
                  "!/META-INF/MANIFEST.MF")
    (URL.)
    (.openStream)
    (Manifest.)
    (.getMainAttributes)
    (.getValue "Build-number")))

Попробуй это. Там нет необходимости для функции. def внутри defn должны прозвенеть тревожные звонки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...