Racket编程指南——21 运行和创建可执行文件
21 运行和创建可执行文件
在开发程序时,很多Racket程序员使用DrRacket编程环境。要在没有开发环境的情况下运行程序,请使用racket(用于基于控制台的程序)或gracket(对于GUI程序)。本章主要介绍如何运行racket和gracket。
21.1 运行racket和gracket |
21.1.1 交互模式 |
21.1.2 模块模式 |
21.1.3 加载模式 |
21.2 脚本 |
21.2.1 Unix脚本 |
21.2.2 Windows批处理文件 |
21.3 创建独立可执行文件 |
21.1 运行racket和gracket
gracket可执行文件和racket一样,但表现上有小的调整,可作为GUI应用程序而不是控制台应用程序。例如,gracket在默认情况下以交互模式运行,使用GUI窗口而不是控制台提示符。然而,GUI应用程序可以以普通的racket运行。
根据命令行参数的不同,racket或gracket在交互模式、模块模式或加载模式下。
21.1.1 交互模式
当racket在没有命令行参数的情况下运行时(除了配置选项,如-j),那么启动REPL使用> 提示符:
Welcome to Racket v8.4 [cs]. |
> |
为了增强你的REPL体验,请参见《xrepl》;有关GNU Readline支持的信息,请参见《readline》。
要初始化REPL的环境,racket首先需要racket/init模块,该模块提供所有racket,并安装pretty-print以显示结果。最后,在启动REPL之前,racket加载(find-system-path 'init-file)报告的文件(如果存在)。
如果提供了任何命令行参数(配置项除外),请添加-i或--repl以重启REPL。例如,
racket -e '(display "hi\n")' -i
在启动时显示“hi”,但仍显示REPL。
如果需要标志的模块出现在-i/--repl之前,它们将取消对racket/init的自动需求。这种行为可用来使用其它语言初始化REPL的环境。例如,
racket -l racket/base -i
使用更小的初始语言(加载速度更快)启动REPL。请注意,大多数模块都不提供Racket的基本语法,包括函数调用语法和require。例如,
racket -l racket/date -i
生成一个对每个表达式都失败的REPL,因为racket/date只提供了几个函数,而不是REPL里需要求值顶层函数调用所需的#%top-interaction和#%app绑定。
如果一个需求标志的模块出现在-i/--repl之后,而不是出现在它之前,那么该模块需要在racket/init之后,以增强初始环境。例如,
racket -i -l racket/date
除了racket的导出之外,可以使用racket/date启动一个有用的REPL。
21.1.2 模块模式
如果一个文件参数在任何命令行开关(除了其它配置选项)之前提供给racket,那么这个文件作为一个模块导入,没有REPL启动。例如,
racket hello.rkt
需求"hello.rkt"模块,然后退出。文件名、标志或其它内容之后的任何参数都作为命令行参数保存,以供所需的模块通过current-command-line-arguments使用。
如果使用命令行标志,则可以使用-u或--require-script标志来显示地将文件作为模块。-t或--require标志类似,只是额外的命令行标志由racket处理,而不是为需求的模块保留。例如,
racket -t hello.rkt -t goodbye.rkt
需求"hello.rkt"模块,然后需求"goodbye.rkt"模块,再然后退出。
-l或--lib标志类似于-t/--require,但它需求一个使用lib模块路径而不是文件路径的模块。例如,
racket -l raco
与运行不带参数的raco可执行文件是一样的,因为raco模块是可执行文件的主模块。
请注意,如果你想将命令行标志传递给上面的raco,你需要用--保护这些标志,这样racket就不会试图自己解析它们:
racket -l raco -- --help
21.1.3 加载模式
-f或--load标志直接支持文件中的load顶级表达式,而不是模块文件中的表达式。这个求值就像启动一个REPL并直接键入表达式,只是结果不打印。例如,
racket -f hi.rkts
load "hi.rkts"并退出。请注意,由于给有LISP/Scheme经验的读者的一个说明中解释的原因,加载模式通常是一个坏主意;使用模块模式通常更好。
-e或--eval标志接受表达式直接求值。与文件加载不同,表达式的结果是打印的,就像在REPL中一样。例如,
racket -e '(current-seconds)'
打印自1970年1月1日以来的秒数。
对于文件加载和表达式求值,顶级环境的创建方式与交互模式相同:除非首先指定了另一个模块,否则需求racket/init。例如,
racket -l racket/base -e '(current-seconds)'
很可能运行得更快,因为它使用较小的racket/base语言而不是racket/init初始化求值环境。
21.2 脚本
Racket文件可以在UNIX和Mac OS上转换为可执行脚本。在Windows中,像Cygwin这样的兼容层支持相同类型的脚本,或者可以将脚本实现为批处理文件。
21.2.1 Unix脚本
在UNIX环境(包括Linux和Mac OS)中,可以使用shell的#!约定将Racket文件转换为可执行脚本。文件的前两个字符必须是#!;下一个字符必须是空格或/,并且第一行的其余部分必须是执行脚本的命令。对于某些平台,第一行的总长度限制为32个字符,而且有时需要空间。
使用#lang racket/base代替#lang racket来生成启动时间更快的脚本。
最简单的脚本格式使用racket可执行文件的绝对路径,随后是模块声明。例如,如果racket安装在"/usr/local/bin"中,那么包含以下文本的文件将充当“Hello World”脚本:
#! /usr/local/bin/racket |
#lang racket/base |
"Hello, world!" |
特别是,如果将上述内容放入文件"hello"中,并使该文件可执行(例如,使用chmod a+x hello),然后在shell提示符处键入./hello将生成输出"Hello, world!"。
上述脚本之所以有效,是因为操作系统自动将脚本的路径作为#!启动的程序的参数行,并且因为racket将单个非标志参数视为包含要运行的模块的文件。
一种流行的代替方法是,不指定racket可执行文件的完整路径,而是需求racket位于用户的命令路径中,然后“trampoline“使用/usr/bin/env:
#! /usr/bin/env racket |
#lang racket/base |
"Hello, world!" |
在任何一种情况下,脚本的命令行参数都可以通过current-command-line-arguments获得:
#! /usr/bin/env racket |
#lang racket/base |
(printf "Given arguments: ~s\n" |
(current-command-line-arguments)) |
如果需要脚本的名称,可以通过(find-system-path 'run-file)获取,而不是(current-command-line-arguments)。
通常,处理命令行参数的最佳方法是使用racket提供的command-line表解析它们。默认情况下,command-line表从(current-command-line-arguments)中提取命令行参数:
#! /usr/bin/env racket |
#lang racket |
(define verbose? (make-parameter #f)) |
(define greeting |
(command-line |
#:once-each |
[("-v") "Verbose mode" (verbose? #t)] |
#:args |
(str) str)) |
(printf "~a~a\n" |
greeting |
(if (verbose?) " to you, too!" "")) |
尝试使用--help标志运行上述脚本,以查看脚本允许哪些命令行参数。
更普通的trampoline使用/bin/sh加上一些行,这些行是一种语言的注释,另一种语言是表达式。这个trampoline更复杂,但它提供了对racket命令行参数的更多控制:
#! /bin/sh |
#| |
exec racket -e '(printf "Running...\n")' -u "$0" ${1+"$@"} |
|# |
#lang racket/base |
(printf "The above line of output had been produced via\n") |
(printf "a use of the `-e' flag.\n") |
(printf "Given arguments: ~s\n" |
(current-command-line-arguments)) |
请注意,#!在Racket中开始一行注释,#|...|#形成块注释。同时,#还启动了一个shell脚本注释,而exec racket则中止了shell脚本以启动racket。这样,脚本文件就变成了/bin/sh和racket的有效输入。
21.2.2 Windows批处理文件
类似的技巧也可以用于在windows中编写Racket代码.bat批处理文件:
; @echo off |
; Racket.exe "%~f0" %* |
; exit /b |
#lang racket/base |
"Hello, world!" |
21.3 创建独立可执行文件
有关创建和分发可执行文件的信息,参见在《(part ("(lib scribblings/raco/raco.scrbl)" "top"))》中的(part ("(lib scribblings/raco/raco.scrbl)" "exe"))》和《(part ("(lib scribblings/raco/raco.scrbl)" "exe-dist"))》。
(part ("(lib scribblings/raco/raco.scrbl)" "top")).
Racket编程指南——21 运行和创建可执行文件相关推荐
- Racket编程指南——23 Racket和Scheme的方言
23 Racket和Scheme的方言 我们使用"Racket"来指Lisp语言的一种特定方言,它基于Lisp家族的Scheme分支.尽管Racket与Scheme相似,但模块上的 ...
- Racket编程指南——4 表达式和定义
4 表达式和定义 <Racket概要>这一章介绍了一些基本的Racket的句法表:定义.过程程序.条件表达式等等.本节提供这些形式的更详细信息,以及一些附加的基本表. 4.1 标记法 4. ...
- Racket编程指南——8 输入和输出
8 输入和输出 一个Racket端口对应一个流的Unix概念(不要与racket/stream的流混淆). 一个Racket端口(port)代表一个数据源或数据池,诸如一个文件.一个终端.一个TCP连 ...
- Racket编程指南——20 并行
20 并行 Racket提供两种形式的并行(parallelism):前程(futures)和现场(places).在提供多个处理器的平台上,并行可以提高程序的运行时性能. 关于Racket里顺序性能 ...
- Racket编程指南——13 类和对象
13 类和对象 本章基于一篇论文[Flatt06]. 一个类(class)表达式表示一类值,就像一个lambda表达式一样: (class superclass-expr decl-or-expr . ...
- iOS_SpriteKit_02_SpriteKit编程指南
关于Sprite Kit SpriteKit提供了一个图形渲染(rendering)和动画的基础,你可以使用它让任意纹理(textured)图像或精灵动起来.Sprite Kit采用的是传统的渲染循环 ...
- iPhone OS编程指南(一)
原文地址:iPhone OS编程指南(一)作者:若水一叶 介绍 请注意:本文档之前命名为iPhone OS编程指南. iPhoneSDK为创建iPhone的本地应用程序提供必需的工具和资源.在用户的H ...
- OpenGL编程指南(第八版)第一个渲染三角形案例代码在win8双显卡电脑VS2015中运行方法总结
弄了好几天才把第一个程序运行出来,用该博客记录一下参考的博客资料及问题: 写得很好的博客参考资料为: http://blog.csdn.net/IceTeaSet/article/details/50 ...
- OpenGL编程指南4:双缓冲实现运行
1.前言 绘制一个旋转的方块,主要为了说明glutSwapBuffers()函数的用法. 同时也为了学习如何使用GLUT控制输入设备,并打开或关闭空闲处理函数. 2.OpenGL编程及程序剖析 /** ...
最新文章
- 树莓派Python编程指南--第一章(起航--启动和运行)
- .NET Core快速入门教程 3、我的第一个.NET Core App (CentOS篇)
- 如何使用Java和XML Config在Spring Security中启用HTTP基本身份验证
- AS3的Number类型变量不指定初始值,则其初始值为NaN,而不是0.0
- 5G标准化加速 需应对测试场景复杂性
- python连接mysql查询数据返回字典格式
- azure云数据库_在Azure SQL数据库中实现动态数据屏蔽
- Python基础笔记(二) List、tuple、循环语句
- win10创建mysql数据库吗_win10 sqlite3创建的数据库文件在哪
- Advanced clustering methods (Cure, Chameleon, Rock, Jarvis-Petrich)
- 阿里云云计算 52在线实验--云监控初体验
- 华为ensp 交换机vlan配置
- 外螺纹对照表_螺纹符号对照表[1]
- 彐一夕儿本铺_2019-10-16汉字宫目录
- 【复杂网络社团发现】Gephi绘制网络图
- 《算法导论》第16章-贪心算法 16.1-活动选择问题(含C++代码)
- 二次函数回归方程_高三||【高三专题】三角函数提优专题卷
- 工作日记:JavaScript生成随机色
- [附源码]计算机毕业设计JAVA领导干部听课评课管理系统
- Cannot run program‘C:\Anaconda3\envs\...\python.exe’(in directory):CreateProcess error=2,系统找不到指定文件
热门文章
- 【NAS】Samba配置文件解析
- Mac之如何将文件夹加入个人收藏
- Rockchip RK3288型号获取
- 华为设备AP管理命令
- 论文笔记(三):PoseCNN: A Convolutional Neural Network for 6D Object Pose Estimation in Cluttered Scenes
- 计算机无法连接网络错误651,651错误代码,详细教您宽带连接提示错误651怎么办...
- 阿里云ECS服务器 跨域Access-Control-Allow-Origin 问题
- 信捷PLC以太网通讯数据采集解决方案
- 判决文书网爬虫获取vjkl5失败原因
- 微软服务器改dns,Win10修改微软DNS的方法!