生成字符串并在运行时将它们作为程序执行
这是一个很难说清楚的问题,我不确定它的正确术语是什么(如果有的话)。我很好奇什么语言允许您在程序执行期间“构建”字符串,然后将其作为程序的一部分执行。据我所知,唯一可以做到这一点的语言是 Snobol。
然而,阅读 Tcl 的维基百科条目,听起来它也可以做到这一点?
我一直认为这是一个很棒的功能,即使它可能不会被经常使用。谢谢。
PS:会用 Snobol、Spitbol 标记此内容,但没有创建新标记的声誉。
This is a tough question to word and I'm not sure what the proper term for it would be (if any). I'm curious what languages allow you to "build up" a string during program execution, and then execute it as part of the program. The only language that I know of that allows you to do this is Snobol.
Reading the wikipedia entry for Tcl however, it sounds like it may be able to do this also?
I always thought this was a nifty feature even if it may not be used much. Thanks.
PS: Would tag this with Snobol, Spitbol, but don't have the reputation to create new tags.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
寻找支持
eval
的语言,或者更一般地说,运行时元编程。几乎每种语言都支持 eval(甚至像 Haskell 这样的强静态类型语言)。许多为主要通过字节码实现的语言构建的运行时解释(例如类似 Lisp 的语言、Erlang 或 Java)支持以下功能:
在运行时插入新的(字节)代码。一旦可以动态插入新代码,您就可以编写
eval
,或者进行“猴子修补”。即使在没有对完整元编程甚至动态链接的特定支持的语言实现中,通常也有一些方法可以在程序员控制下动态生成代码,通过反射机制或代码生成支持库(例如 LLVM)。
除了简单的单阶段评估之外,更普遍的是,支持多阶段计算的语言允许为任意数量的阶段生成从一个阶段到下一个阶段的程序,使得安全、任意嵌套
evals
成为可能。引用 Taha 的关于多阶段编程的论文< /a> models 介绍了很多理论。
您正在寻找的语言通常以某种形式提供三种原语:
,用于将计算延迟一个阶段(例如,将片段作为字符串引用),将其拼接到正在运行的程序中,然后执行该片段(在 Lisp 中,反引号、逗号和 eval)。
Lisp 和评估
eval
将 eval 推广到多阶段编程
关于多阶段编程:
为多阶段编程提供类型
多阶段计算的形式化描述非常棘手,并且涉及不寻常的技术(对于编程语言),例如模态逻辑。
为元程序提供类型:
安全问题
形式化多阶段编程语义的棘手之处解释了为什么它们经常使系统难以使用,以及为什么
eval
会引发如此多的安全问题:不清楚什么代码在何时执行,以及到底什么数据被转换为代码。从一个阶段到下一阶段进行名称捕获是很棘手的,这会导致代码注入攻击。这种复杂性无助于安全性。Look for languages that support
eval
, or, more generally, runtime meta-programming. Pretty much every language supports aneval
(even strongly, statically typed languages like Haskell). Many runtimes built for languages that are primarily implemented via bytecodeinterpretation (such as Lisp-like languages, Erlang or Java) support the ability to
insert new (byte)code at runtime. Once you can insert new code dynamically, you can write
eval
, or do "monkey patching".Even in language implementations without specific support for full meta-programming, or even dynamic linking, there are often ways to dynamically generate code under programmer control, either via reflection mechanisms or code generation support libraries (such as LLVM).
Beyond just a simple one-stage
eval
, more generally, languages that support multi-stage computation allow for generation of programs from one stage to the next, for arbitrary numbers of stages, making it possible to safely, arbitrarily nestevals
.To quote Taha, who's thesis on multi-stage programming models introduces much of the theory.
The languages you're looking for usually provide three primitives, in some form or another:
for delaying computation by one stage (e.g. quoting a fragment as a string), splicing it into a running program, and executing that fragment (in Lisp, back-quote, comma, and eval).
Lisp and eval
eval
Generalizing eval to multi-stage programming
On multi-stage programming:
Giving types to multi-stage programming
Formal descriptions of multi-stage computation are quite tricky, and involve unusual techniques (for programming languages) like modal logic.
Giving types to meta-programs:
Security issues
The trickiness of formalzing the semantics of multi-stage programming explains why they're often confusing systems to work with, and why
eval
can open up so many security concerns: it becomes unclear what code is executing when, and exactly what data is being turned into code. Getting name capture from one stage to the next is tricky, leading to code injection attacks. Such complexity doesn't help security.绝对可以用许多解释性脚本语言来完成。有些语言是专门为此设计的。据我所知,它可以在以下语言中完成:
Definitely can be done in a lot of interpreted scripting languages. And some languages are specifically designed for this. It can be done, to my knowledge, in:
它可以在所有 Lisp 方言中完成,该功能起源于名称
eval
,也可以在 Prolog (call/1
) 和任何其他语言中完成。大多数保留名称eval
并且大多数是动态语言。话虽这么说,这并不是一个漂亮的功能。考虑到滥用此功能是多么容易,我将其称为主要安全问题。如果您想要动态执行代码,那么编写您自己的、受限制的微解释器(或使用 Lua 之类的东西)几乎总是一个更好的主意。
It can be done in all Lisp dialects, where this feature originated under the name
eval
, as well as in Prolog (call/1
) and any number of other languages. Most keep the nameeval
and most are dynamic languages.That being said, this is hardly a nifty feature. I'd call it a major security issue, given how easy it is to abuse this feature. If you want dynamic code execution, then writing your own, restricted, micro-interpreter (or using something like Lua) is almost always a better idea.