Clojure:在REPL加载依赖 [英] Clojure : loading dependencies at the REPL

查看:229
本文介绍了Clojure:在REPL加载依赖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近得知(由于技术原因)在REPL ---

I recently learned (thanks to technomancy) that, at the REPL ---

这会失败:

user=> (:require [clojure.set :as set])
java.lang.ClassNotFoundException: clojure.set (NO_SOURCE_FILE:24)

成功的例子:

user=> (require '[clojure.set :as cs]) 
nil



.set类。

at loading the clojure.set class.

上下文:前一行是从命名空间的源文件复制的

我的主要问题是:我们所做的更改是通过交换:和'字符,现在允许后一个命令成功。

我的第二个问题是,一般来说 - 在REPL做事情的准则是什么?与在正常clojure源文件中做事情相比?假设我们可以从LEININGEN项目的根目录加载我们的repl,所以至少jar在依赖项子目录中的磁盘上可用。

My 2nd question is , in general - what are the guidelines for doing things at the REPL --- as compared with doing things in normal clojure source files ? Assume here that we can load our repl from the root of a LEININGEN project, so at least the jars will be available on disk in the dependencies sub directory.

推荐答案

我将从高级别转到您的特定问题:

I'll go from high-level down to your particular problem:

REPL或Read-Eval-Print Loops是LISP设计的核心:

REPLs, or Read-Eval-Print Loops are the core of how LISPs are designed:


  • 阅读器将字符流转换为数据结构(称为阅读器表单)。

  • 评估者会收集读者表单并对其进行评估。

  • 打印机发出评估者的结果。
  • The reader converts a stream of characters into data structures (called Reader Forms).
  • The evaluator takes collection of reader forms and evaluates them.
  • The printer emits the results of the evaluator.

因此,当您在REPL中输入文本时,它会通过每个步骤来处理您的输入并将输出返回到您的终端。

So when you enter text into a REPL, it goes through each of these steps to process your input and return the output to your terminal.

第一部分,clojure阅读器表单。这将非常简短,我鼓励您阅读或观看(第1部分第2部分)。

First some, clojure reader forms. This will be extremely brief, I encourage you to read or watch (part 1, part 2) about it.

clojure中的符号是可以表示特定值(如变量)的形式。符号本身可以作为数据传递。它们类似于c中的指针,只是没有内存管理的东西。

A symbol in clojure is form that can represent a particular value (like a variable). Symbols themselves can be pass around as data. They are similar to pointers in c, just without the memory management stuff.

前面有冒号的符号是一个关键字。关键字就像符号,但关键字的值总是自己 - 类似于字符串或数字。它们与Ruby的符号(也以冒号作为前缀)相同。

A symbol with a colon in front of it is a keyword. Keywords are like symbols with the exception that a keyword's value are always themselves - similar to strings or numbers. They're identical to Ruby's symbols (which are also prefixed with colons).

表单前面的引用会告诉评估者离开数据结构为:

A quote in front of a form tells the evaluator to leave the data structure as-is:

user=> (list 1 2)
(1 2)
user=> '(1 2)
(1 2)
user=> (= (list 1 2) '(1 2))
true

应用于不仅仅是列表,它主要用于列表,因为clojure的求值器通常将执行列表作为函数式调用。使用'是引用宏的缩写:

Although quoting can apply to more than just lists, it's primarily used for lists because clojure's evaluator will normally execute lists as a function-like invocation. Using the ' is shorthand to the quote macro:

user=> (quote (1 2)) ; same as '(1 2)
(1 2)

引用基本上指定数据结构返回而不是实际代码来执行。因此,您可以引用符号的符号。

Quoting basically specifies data structure to return and not actual code to execute. So you can quote symbols which refers to the symbol.

user=> 'foo ; not defined earlier
foo

并且引用是递归的。所以里面的所有数据都是引用的:

And quoting is recursive. So all the data inside are quoted too:

user=> '(foo bar)
(foo bar)

$ c>(foo bar)没有引号,你可以eval它:

To get the behavior of (foo bar) without quoting, you can eval it:

user=> (eval '(foo bar)) ; Remember, foo and bar weren't defined yet.
CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:1)
user=> (def foo identity)
#'user/foo
user=> (def bar 1)
#'user/bar
user=> (eval '(foo bar))
1

对于require语句,我假设你发现前者形式为:

As for require statements, I'm assuming you found the former in the form of:

(ns my.namespace
    (:require [clojure.set :as set]))

ns http://clojure.org/macros\"> macro ,它会将:require表达式转换为您所描述的后一种形式:

ns is a macro that will transform the :require expression into the latter form you described:

(require '[clojure.set :as set])

工作。

user=> (doc ns)
-------------------------
clojure.core/ns
([name docstring? attr-map? references*])
Macro
  Sets *ns* to the namespace named by name (unevaluated), creating it
  if needed.  references can be zero or more of: (:refer-clojure ...)
  (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class)
  with the syntax of refer-clojure/require/use/import/load/gen-class
  respectively, except the arguments are unevaluated and need not be
  quoted. (:gen-class ...), when supplied, defaults to :name
  corresponding to the ns name, :main true, :impl-ns same as ns, and
  :init-impl-ns true. All options of gen-class are
  supported. The :gen-class directive is ignored when not
  compiling. If :gen-class is not supplied, when compiled only an
  nsname__init.class will be generated. If :refer-clojure is not used, a
  default (refer 'clojure) is used.  Use of ns is preferred to
  individual calls to in-ns/require/use/import:



< h2> REPL使用

一般来说,不要在REPL中使用 ns ,只需使用 require 使用函数。但在文件中,使用 ns 宏来执行这些操作。

REPL usage

In general, don't use ns in the REPL, and just use the require and use functions. But in files, use the ns macro to do those stuff.

这篇关于Clojure:在REPL加载依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆