Программа работает в репле но больше нигде?

Я подозреваю, что это может быть связано с java-interop, поскольку я вызываю много функций java в своем коде.

Когда я запускаю следующее в своем REPL (через emacs), он работает точно так, как должен

  (def height 100)
  (def image (BufferedImage. width height BufferedImage/TYPE_INT_ARGB))
  (def graphics (.createGraphics image))

  (.setColor graphics Color/black)
  (for [x (range 0 width 10)]
    (.drawLine graphics x 0 x height ))
  (for [y (range 0 height 10)]
    (.drawLine graphics 0 y width y))
  (ImageIO/write image "png" (io/file "output.png"))

Изображение сетки сгенерировано правильно.

Однако, если я делаю C-c C-k, он генерирует пустое изображение.

Теперь, когда я втыкаю его в функцию и запускаю через lein run, я получаю предупреждение, которого не понимаю:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/1832669781 (file:/home/n/.m2/repository/org/clojure/clojure/1.10.0/clojure-1.10.0.jar) to method sun.java2d.SunGraphics2D.setColor(java.awt.Color)
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/1832669781
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Я очень мало знаю о clojure и еще меньше о java, но я использую openjdk 10.

Я считаю, что мой код написан правильно (хотя и плохо), это проблема с моим кодом или это clojure?


person namgo    schedule 07.03.2019    source источник


Ответы (1)


Я подозреваю, что проблема у вас в том, что for не делает того, что вы думаете. Он генерирует ленивую последовательность. В REPL принтер, как правило, оценивает их, а автономный код — нет.

Попробуйте заменить for на dosq. Это с готовностью выполнит ваши побочные эффекты и должно улучшить ситуацию.

Предупреждения о незаконном доступе — отвлекающий маневр. С тех пор, как появилась модульная система Java, существуют определенные шаблоны взаимодействия, которые их генерируют. Подробная информация о том, как устранить предупреждения, приведена в часто задаваемых вопросах Clojure по адресу https://clojure.org/guides/faq#illegal_access

person pete23    schedule 07.03.2019
comment
Doseq решил проблему. - person namgo; 07.03.2019
comment
Кстати, вы также можете обернуть вызов for в doall. doseq - лучшее решение здесь, но иногда вы не хотите избавляться от ленивой последовательности, но хотите заставить ее реализоваться. - person Mars; 25.04.2019