Python 习语“if __name__ == '__main__'"的clojure 等价物是什么? [英] What is the clojure equivalent of the Python idiom "if __name__ == '__main__'"?

查看:49
本文介绍了Python 习语“if __name__ == '__main__'"的clojure 等价物是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在涉足 clojure,并且在尝试确定与这个常见的 Python 习语等效的 clojure(和/或 Lisp)时遇到了一些麻烦.

I'm dabbling in clojure and am having a little trouble trying to determine the clojure (and / or Lisp) equivalent of this common python idiom.

习惯用法是在python模块的底部经常有一些测试代码,然后是运行代码的语句,例如:

The idiom is that at the bottom of a python module there is often a bit of test code, and then a statement which runs the code, for example:

# mymodule.py
class MyClass(object):
    """Main logic / code for the library lives here"""
    pass

def _runTests():
    # Code which tests various aspects of MyClass...
    mc = MyClass() # etc...
    assert 2 + 2 == 4

if __name__ == '__main__': _runTests()

这对于简单的临时测试很有用.人们通常会通过编写 from mymodule import MyClass 来使用这个模块,在这种情况下 _runTests() 永远不会被调用,但在最后的代码片段中,你也可以运行它直接从命令行输入 python mymodule.py.

This is useful for simple, ad-hoc testing. One would normally use this module by writing from mymodule import MyClass, in which case _runTests() is never called, but with the snippet at the end, one can also run it by typing python mymodule.py directly from the command line.

Clojure(和/或普通 lisp)中是否有等效的习语?我不是在追求一个完整的单元测试库(好吧,我是,但不是在这个问题中),我只想在一个模块中包含一些代码,该模块只会在某些情况下运行,所以我可以有一种运行我一直在研究的代码的快速方法,但仍允许像普通模块/命名空间一样导入我的文件.

Is there an equivalent idiom in Clojure (and/or common lisp)? I'm not after a full-blown unit testing library (well, I am, but not in this question), I'd just like to include some code in a module which will only be run under some circumstances, so I can have a quick way to run code I've been working on but still allow my file to be imported like a normal module / namespace.

推荐答案

从命令行一遍又一遍地运行 Clojure 脚本并不习惯.REPL 是一个更好的命令行.Clojure 是一个 Lisp,通常会启动 Clojure 并使同一个实例永远运行,并与其交互而不是重新启动它.您可以一次更改一个正在运行的实例中的函数,根据需要运行它们并戳它们.摆脱繁琐而缓慢的传统编辑/编译/调试周期是 Lisps 的一大特色.

It's not idiomatic to run Clojure scripts over and over from the command line. The REPL is a better command line. Clojure being a Lisp, it's common to fire up Clojure and leave the same instance running forever, and interact with it rather than restart it. You can change functions in the running instance one at a time, run them and poke them as needed. Escaping the tedious and slow traditional edit/compile/debug cycle is a great feature of Lisps.

您可以轻松编写函数来执行诸如运行单元测试之类的操作,并且只要您想运行它们时就从 REPL 调用这些函数,否则就忽略它们.在 Clojure 中通常使用 clojure.contrib.test-is,将测试函数添加到命名空间,然后使用 clojure.contrib.test-is/run-tests运行它们.

You can easily write functions to do things like run unit tests, and just call those functions from the REPL whenever you want to run them and ignore them otherwise. It's common in Clojure to use clojure.contrib.test-is, add your test functions to your namespace, then use clojure.contrib.test-is/run-tests to run them all.

不从命令行运行 Clojure 的另一个很好的理由是 JVM 的启动时间可能太长.

Another good reason not to run Clojure from the commandline is that the startup time of the JVM can be prohibitive.

如果您真的想从命令行运行 Clojure 脚本,有很多方法可以做到.有关讨论,请参阅Clojure 邮件列表.

If you really want to run a Clojure script from the command line, there are a bunch of ways you can do it. See the Clojure mailing list for some discussion.

一种方法是测试命令行参数的存在.鉴于当前目录中的这个 foo.clj:

One way is to test for the presence of command line arguments. Given this foo.clj in the current directory:

(ns foo)

(defn hello [x] (println "Hello," x))

(if *command-line-args*
  (hello "command line")
  (hello "REPL"))

根据您启动 Clojure 的方式,您将获得不同的行为.

You'll get different behavior depending how you start Clojure.

$ java -cp ~/path/to/clojure.jar:. clojure.main foo.clj --
Hello, command line
$ java -cp ~/path/to/clojure.jar:. clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=> (use 'foo)
Hello, REPL
nil
user=>

如果您想了解这是如何工作的,请参阅 Clojure 源代码中的 src/clj/clojure/main.clj.

See src/clj/clojure/main.clj in the Clojure source if you want to see how this is working.

另一种方法是将您的代码编译成 .class 文件并从 Java 命令行调用它们.给定一个源文件 foo.clj:

Another way is to compile your code into .class files and invoke them from the Java command line. Given a source file foo.clj:

(ns foo
  (:gen-class))

(defn hello [x] (println "Hello," x))

(defn -main [] (hello "command line"))

创建一个目录来存放编译好的.class文件;这默认为 ./classes.你必须自己创建这个文件夹,Clojure 不会创建它.还要确保将 $CLASSPATH 设置为包含 ./classes 和包含源代码的目录;我假设 foo.clj 在当前目录中.所以从命令行:

Make a directory to store the compiled .class files; this defaults to ./classes. You must make this folder yourself, Clojure won't create it. Also make sure you set $CLASSPATH to include ./classes and the directory with your source code; I'll assume foo.clj is in the current directory. So from the command line:

$ mkdir classes
$ java -cp ~/path/to/clojure.jar:./classes:. clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=> (compile 'foo)
foo

classes 目录中,您现在将拥有一堆.class 文件.从命令行调用代码(默认运行 -main 函数):

In the classes directory you will now have a bunch of .class files. To invoke your code from the command line (running the -main function by default):

$ java -cp ~/path/to/clojure.jar:./classes foo
Hello, command line.

clojure.org 上有很多关于编译 Clojure 代码的信息.

There's a lot of information about compiling Clojure code on clojure.org.

这篇关于Python 习语“if __name__ == '__main__'"的clojure 等价物是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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