4

我想使用Lisp Flavored Erlang作为Erlang 应用程序脚本扩展语言。如果您愿意,可以通过Emacs Lisp以类似的方式配置和扩展GNU Emacs

我知道这个论点是广泛而有条理的。但在这个问题的特定情况下,我希望能够从 Erlang 代码中读取 LFE 中定义的绑定名称(或变量,如果您愿意的话)。

我不是LFE内部架构的专家(这是软件工程和 Erlang 编程的一个很好的例子),但我在源代码和文档中都找不到答案。查看源代码我可以看到 LFE 包含一个以Erlang VM为目标的编译器和一个解释器。后者是我正在尝试使用的。

如果我在 LFE 安装路径(在我的系统上)中启动 Erlang shell/ REPL$HOME/opt/lfe


$ cd /path/to/LFE-install-dir
$ erl -pa ./ebin

我能够计算一个值:


1> {ok, Expr} = lfe_io:read_string("(+ 1 10)").
{ok,['+',1,10]}
2> Result = lfe_eval:expr(Expr).
11

这是第一步,但不完全是我想要的。我宁愿绑定一个变量并读取它的值;那是我的问题:


3> {ok, Expr2} = lfe_io:read_string("(set a 10)").
{ok,[set,a,10]}
4> lfe_eval:expr(Expr2).
** exception error: {unbound_func,{set,2}}
     in function  lfe_eval:eval_expr/2

为什么set被识别为未绑定函数?在 LFE REPL 中,这个表达式是有效的:

Erlang/OTP 17 [erts-6.4] [来源] [64 位] [smp:4:4] ...
LFE Shell V6.4(使用 ^G 中止)
>(设置一个10)
10
> 一个
10

我显然以错误的方式使用 API。如何阅读a和/或正确初始化LFE 解释器的内容?

(如果这在某处有解释,请提供参考)。

4

2 回答 2

2

我不会尝试完全回答您关于添加脚本的“最佳实践”的更广泛的问题。在我看来,在“基于钩子”的解决方案(您通过名称约定定义钩子实现并且它们被自动识别)和“显式 api”解决方案(您使用脚本环境中预定义的函数来注册您的钩子)之间进行选择或以其他方式调用配置函数)在很大程度上是一个品味问题。像 (set-connection-timeout-handler ...) 这样的显式调用可能更具可读性,更易于调试(没有拼写错误问题,api 更改没有意外),更容易记录,并且更灵活,但更多,好吧,明确的。

从您的简单变量定义示例构建,您可以通过以下几种方式开始进一步“解释”路径:

1> {ok, Expr} = lfe_io:read_string("'((a 10))").
{ok,[quote,[[a,10]]]}
2> lfe_eval:expr (Expr).
[[a,10]]

3> EvalAll = fun (Conf) -> {ok, E} = lfe_io:read_string("'(" ++ Conf ++ ")"), lfe_eval:expr(E) end.
#Fun<erl_eval.6.90072148>
4> EvalAll ("(a 10) (b 11)").                                                                      
[[a,10],[b,11]]

5> EvalAllL = fun (Conf) -> {ok, E} = lfe_io:read_string("(list " ++ Conf ++ ")"), lfe_eval:expr(E) end.
#Fun<erl_eval.6.90072148>
6> [{f, F}] = EvalAllL ("(tuple 'f (lambda (x) (+ 10 x)))").
[{f,#Fun<lfe_eval.12.2018457>}]
7> F (12).
22

8> G = fun (X) -> X * 2 end.
#Fun<erl_eval.6.90072148>
9> lfe_eval:expr (element (2, lfe_io:read_string ("(g 15)")), lfe_eval:add_lexical_func(g, 1, G, lfe_env:new ())).
30
于 2015-06-05T18:23:25.777 回答
2

一种简单的方法是使用“lfe”命令来运行 LFE 脚本。'lfe' 的行为方式与 'bash' 类似,您可以使用它来运行脚本。bin/lfec 中定义的“lfec”脚本就是一个很好的例子。它是一个 LFE shell 脚本,它解析它的参数并运行 LFE 编译器。

于 2015-06-06T04:25:41.167 回答