哪个是Clojure全局变量?

时间:2017-04-17 13:04:32

标签: clojure

Clojure代码中总是存在哪些全局变量? Leiningen docs提示它们的列表及其有意义的值。但是我找不到它。

2 个答案:

答案 0 :(得分:6)

一个开始就是列出全局变量,#clojure@irc.freenode.net帮助的一些问题:

(filter #(re-find #"^\*.+\*$" (str %)) (keys (ns-publics 'clojure.core)))
=> (*print-namespace-maps* *source-path* *command-line-args* *read-eval* *verbose-defrecords* *print-level* *suppress-read* *print-length* *file* *use-context-classloader* *err* *default-data-reader-fn* *allow-unresolved-vars* *print-meta* *compile-files* *math-context* *data-readers* *clojure-version* *unchecked-math* *out* *warn-on-reflection* *compile-path* *in* *ns* *assert* *print-readably* *flush-on-newline* *agent* *fn-loader* *compiler-options* *print-dup*)

现在我们只需要为这个列表中的每个变量附加一些语义。我们可以在docs中逐个查找它们,但由于当前值和docstring在运行时可用,我们也可以通过编程方式查找它们。

(for [[sym varr] (ns-publics 'clojure.core)
      :when (re-matches #"\*.+\*" (name sym))]
  [varr @varr (:doc (meta varr))])
=>
([*print-namespace-maps*
  true
  "*print-namespace-maps* controls whether the printer will print
  namespace map literal syntax. It defaults to false, but the REPL binds
  to true."]
 [*source-path* "NO_SOURCE_FILE" nil]
 [*command-line-args*
  ("repl")
  "A sequence of the supplied command line arguments, or nil if
  none were supplied"]
 [*read-eval*
  true
  "Defaults to true (or value specified by system property, see below)
  ***This setting implies that the full power of the reader is in play,
  including syntax that can cause code to execute. It should never be
  used with untrusted sources. See also: clojure.edn/read.***

  When set to logical false in the thread-local binding,
  the eval reader (#=) and record/type literal syntax are disabled in read/load.
  Example (will fail): (binding [*read-eval* false] (read-string \"#=(* 2 21)\"))

  The default binding can be controlled by the system property
  'clojure.read.eval' System properties can be set on the command line
  like this:


  java -Dclojure.read.eval=false ...

  The system property can also be set to 'unknown' via
  -Dclojure.read.eval=unknown, in which case the default binding
  is :unknown and all reads will fail in contexts where *read-eval*
  has not been explicitly bound to either true or false. This setting
  can be a useful diagnostic tool to ensure that all of your reads
  occur in considered contexts. You can also accomplish this in a
  particular scope by binding *read-eval* to :unknown
  "]
 [*verbose-defrecords* false nil]
 [*print-level*
  nil
  "*print-level* controls how many levels deep the printer will
  print nested objects. If it is bound to logical false, there is no
  limit. Otherwise, it must be bound to an integer indicating the maximum
  level to print. Each argument to print is at level 0; if an argument is a
  collection, its items are at level 1; and so on. If an object is a
  collection and is at a level greater than or equal to the value bound to
  *print-level*, the printer prints '#
' to represent it. The root binding
  is nil indicating no limit."]
 [*suppress-read* nil nil]
 [*print-length*
  nil
  "*print-length* controls how many items of each collection the
  printer will print. If it is bound to logical false, there is no
  limit. Otherwise, it must be bound to an integer indicating the maximum
  number of items of each collection to print. If a collection contains
  more items, the printer will print items up to the limit followed by
  '...' to represent the remaining items. The root binding is nil
  indicating no limit."]
 [*file*
  "/home/rovanion/source/clojure/leiningen/leiningen-core/src/leiningen/core/spec/project.clj"
  "The path of the file being evaluated, as a String.

  When there is no file, e.g. in the REPL, the value is not defined."]
 [*use-context-classloader* true nil]
 [*err*
  #object[java.io.PrintWriter 0x5ba803 "java.io.PrintWriter@5ba803"]
  "A java.io.Writer object representing standard error for print operations.

  Defaults to System/err, wrappe
d in a PrintWriter"]
 [*default-data-reader-fn*
  nil
  "When no data reader is found for a tag and *default-data-reader-fn*
  is non-nil, it will be called with two arguments,
  the tag and the value.  If *default-data-reader-fn* is nil (the
  default), an exception will be thrown for the unknown tag."]
 [*allow-unresolved-vars* false nil]
 [*print-meta*
  false
  "If set to logical true, when printing an object, its metadata will also
  be printed in a form that can be read back by the reader.

  Defaults to false."]
 [*compile-files*
  false
  "Set to true when compiling files, false otherwise."]
 [*math-context* nil nil]
 [*data-readers*
  {}
  "Map from reader tag symbols to data reader Vars.

  When Clojure starts, it searches for files named 'data_readers.clj'
  at the root of the classpath. Each such file must contain a literal
  map of symbols, like this:

      {foo/bar my.project.foo/bar
       foo/baz my.project/baz}

  The first symbol in each pair is a tag that will be recognized
by
  the Clojure reader. The second symbol in the pair is the
  fully-qualified name of a Var which will be invoked by the reader to
  parse the form following the tag. For example, given the
  data_readers.clj file above, the Clojure reader would parse this
  form:

      #foo/bar [1 2 3]

  by invoking the Var #'my.project.foo/bar on the vector [1 2 3]. The
  data reader function is invoked on the form AFTER it has been read
  as a normal Clojure data structure by the reader.

  Reader tags without namespace qualifiers are reserved for
  Clojure. Default reader tags are defined in
  clojure.core/default-data-readers but may be overridden in
  data_readers.clj or by rebinding this Var."]
 [*clojure-version*
  {:major 1, :minor 9, :incremental 0, :qualifier "alpha15"}
  "The version info for Clojure core, as a map containing :major :minor
  :incremental and :qualifier keys. Feature releases may increment
  :minor and/or :major, bugfix releases will increment :incremental.
  Possible valu
es of :qualifier include \"GA\", \"SNAPSHOT\", \"RC-x\" \"BETA-x\""]
 [*unchecked-math*
  false
  "While bound to true, compilations of +, -, *, inc, dec and the
  coercions will be done without overflow checks. While bound
  to :warn-on-boxed, same behavior as true, and a warning is emitted
  when compilation uses boxed math. Default: false."]
 [*out*
  #<Writer$IDeref$PrettyFlush$4923d848@8c3230:  ...>
  "A java.io.Writer object representing standard output for print operations.

  Defaults to System/out, wrapped in an OutputStreamWriter"]
 [*warn-on-reflection*
  nil
  "When set to true, the compiler will emit warnings when reflection is
  needed to resolve Java method calls or field accesses.

  Defaults to false."]
 [*compile-path*
  "/home/rovanion/source/clojure/leiningen/target/classes"
  "Specifies the directory where 'compile' will write out .class
  files. This directory must be in the classpath for 'compile' to
  work.

  Defaults to \"classes\""]
 [*in*
  #object[clojure.lang.LineNumberingPushbackReader 0xfde0fe "clojure.lang.LineNumberingPushbackReader@fde0fe"]
  "A java.io.Rea
der object representing standard input for read operations.

  Defaults to System/in, wrapped in a LineNumberingPushbackReader"]
 [*ns*
  #namespace[leiningen.core.spec.project]
  "A clojure.lang.Namespace object representing the current namespace."]
 [*assert* true nil]
 [*print-readably*
  true
  "When set to logical false, strings and characters will be printed with
  non-alphanumeric characters converted to the appropriate escape sequences.

  Defaults to true"]
 [*flush-on-newline*
  true
  "When set to true, output will be flushed whenever a newline is printed.

  Defaults to true."]
 [*agent*
  nil
  "The agent currently running an action on this thread, else nil"]
 [*fn-loader* nil nil]
 [*compiler-options*
  nil
  "A map of keys to options.
  Note, when binding dynamically make sure to merge with previous value.
  Supported options:
  :elide-meta - a collection of metadata keys to elide during compilation.
  :disable-locals-clearing - set to true to disable clearing, useful for using a deb
ugger
  Alpha, subject to change."]
 [*print-dup*
  false
  "When set to logical true, objects will be printed in a way that preserves
  their type when read in later.

  Defaults to false."])

答案 1 :(得分:1)

关于Clojurians Slack的Noisesmith认为你可以使用apropos找到全局变量:

(ins)user=> (apropos #"^\*.*\*$")
(clojure.core/*agent* clojure.core/*allow-unresolved-vars* clojure.core/*assert* clojure.core/*clojure-version* clojure.core/*command-line-args* clojure.core/*compile-files* clojure.core/*compile-path* clojure.core/*compiler-options* clojure.core/*data-readers* clojure.core/*default-data-reader-fn* clojure.core/*err* clojure.core/*file* clojure.core/*flush-on-newline* clojure.core/*fn-loader* clojure.core/*in* clojure.core/*math-context* clojure.core/*ns* clojure.core/*out* clojure.core/*print-dup* clojure.core/*print-length* clojure.core/*print-level* clojure.core/*print-meta* clojure.core/*print-namespace-maps* clojure.core/*print-readably* clojure.core/*read-eval* clojure.core/*source-path* clojure.core/*suppress-read* clojure.core/*unchecked-math* clojure.core/*use-context-classloader* clojure.core/*verbose-defrecords* clojure.core/*warn-on-reflection* clojure.core.server/*session* clojure.java.browse/*open-url-script* clojure.java.javadoc/*core-java-api* clojure.java.javadoc/*feeling-lucky* clojure.java.javadoc/*feeling-lucky-url* clojure.java.javadoc/*local-javadocs* clojure.java.javadoc/*remote-javadocs* clojure.java.shell/*sh-dir* clojure.java.shell/*sh-env* clojure.pprint/*print-base* clojure.pprint/*print-miser-width* clojure.pprint/*print-pprint-dispatch* clojure.pprint/*print-pretty* clojure.pprint/*print-radix* clojure.pprint/*print-right-margin* clojure.pprint/*print-suppress-namespaces* clojure.spec/*coll-check-limit* clojure.spec/*coll-error-limit* clojure.spec/*compile-asserts* clojure.spec/*explain-out* clojure.spec/*fspec-iterations* clojure.spec/*recursion-limit*)

与之前查找全局变量的方法相比,这不仅包括来自clojure.core的全局变量。